在平面XML文件中创建结构

2024-09-28 20:16:47 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个这样的xml文件:

<car>Ferrari</car>
<color>red</color>
<speed>300</speed>
<car>Porsche</car>
<color>black</color>
<speed>310</speed>

我需要这样的表格:

^{pr2}$

我怎么做?我在挣扎,因为我想不出一种方法来从原始xml文件中的标签的平面lis中创建我需要的结构。在

我选择的语言是Python,但是任何建议都是受欢迎的。在


Tags: 文件方法red标签xmlcar平面表格
3条回答

XSLT是将一种XML结构转换为另一种XML结构的完美工具。在

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <!-- copy the root element and handle its <car> children -->
  <xsl:template match="/root">
    <xsl:copy>
      <xsl:apply-templates select="car" />
    <xsl:copy>
  </xsl:template>

  <!-- car elements become a container for their properties -->
  <xsl:template match="car">
    <car name="{normalize-space()}">
      <!-- ** see 1) -->
      <xsl:copy-of select="following-sibling::color[1]" />
      <xsl:copy-of select="following-sibling::speed[1]" />
    </car>
  </xsl:template>
</xsl:stylesheet>

1)要使这一点起作用,XML必须为每个<car>使用<color><speed>。如果不能保证,或者属性的数量和种类通常是可变的,请将这两行替换为copy语句的泛型形式:

^{pr2}$

应用于您的XML(我暗示了一个名为<root>)的文档元素,这就是结果

<root>
  <car name="Ferrari">
    <color>red</color>
    <speed>300</speed>
  </car>
  <car name="Porsche">
    <color>black</color>
    <speed>310</speed>
  </car>
</root>

在Python中将XSLT应用于XML的示例代码应该很容易找到,所以我在这里省略了。它只需要4到5行Python代码。在

如果现实生活中的数据和示例一样简单,并且其中没有错误,则可以使用正则表达式替换一次性完成:

import re

guff = """
<car>Ferrari</car>
<color>red</color>
<speed>300</speed>
<car>Porsche</car>
<color>black</color>
<speed>310</speed>
"""

pattern = r"""
<car>([^<]+)</car>\s*
<color>([^<]+)</color>\s*
<speed>([^<]+)</speed>\s*
"""

repl = r"""<car name="\1">
    <color>\2</color>
    <speed>\3</speed>
</car>
"""

regex = re.compile(pattern, re.VERBOSE)
output = regex.sub(repl, guff)
print output

否则,最好一次读3行,做一些验证,然后一次写出一个“car”元素,使用字符串处理或ElementTree。在

我不知道python,但是假设您有一个XML解析器,它允许您对XML文档中的节点进行分层访问,那么您想要的语义应该如下所示(警告,我倾向于使用PHP)。基本上,存储所有非“car”标记,然后当您遇到新的“car”标记时,将其视为一个定界字段,并创建组合的XML节点:

// Create an input and output handle
input_handle = parse_xml_document();
output_handle = new_xml_document();

// Assuming the <car>, <color> etc. nodes are
// the children of some, get them as an array
list_of_nodes = input_handle.get_list_child_nodes();

// These are empty variables for storing our data as we parse it
var car, color, speed = NULL

foreach(list_of_nodes as node)
{
  if(node.tag_name() == "speed")
  {
    speed = node.value();
    // etc for each type of non-delimiting field          
  }

  if(node.tag_name() == "car")
  {
    // If there's already a car specified, take its data,
    // insert it into the output xml structure and th
    if(car != NULL)
    {
      // Add a new child node to the output document
      node = output_handle.append_child_node("car");
      // Set the attribute on this new output node
      node.set_attribute("name", node.value());
      // Add the stored child attributes
      node.add_child("color", color);
      node.add_child("speed", speed);
    }

    // Replace the value of car afterwards. This allows the
    // first iteration to happen when there is no stored value
    // for "car".
    car = node.value();

  }
}

相关问题 更多 >