如何使用所需元素获取完整的xml

时间:2014-05-19 12:53:32

标签: python xml xpath elementtree

import xml.etree.ElementTree as ET
tree = ET.parse('country_data.xml')
root = tree.getroot()
for i in tree.findall('.//rank'):
    print ET.tostring(i)

这里我想获得所有排名元素(保持其绝对结构)

我的输出为

<rank>1</rank>

<rank>4</rank>

<rank>68</rank>

如何才能将输出设为

<?xml version="1.0"?>
<data>
    <country name="Liechtenstein">
        <rank>1</rank>
    </country>
    <country name="Singapore">
        <rank>4</rank>
    </country>
    <country name="Panama">
        <rank>68</rank>
    </country>
</data>

当输入xml文件country_data.xml为

<?xml version="1.0"?>
<data>
    <country name="Liechtenstein">
        <rank>1</rank>
        <year>2008</year>
        <gdppc>141100</gdppc>
        <neighbor name="Austria" direction="E"/>
        <neighbor name="Switzerland" direction="W"/> First Country
    </country>
    <country name="Singapore">
        <rank>4</rank>
        <year>2011</year>
        <gdppc>59900</gdppc>
        <neighbor name="Malaysia" direction="N"/> Second Country
    </country>
    <country name="Panama">
        <rank>68</rank>
        <year>2011</year>
        <gdppc>13600</gdppc>
        <neighbor name="Costa Rica" direction="W"/>
        <neighbor name="Colombia" direction="E"/> Third Country
    </country>
</data>

2 个答案:

答案 0 :(得分:2)

您可以使用Python + XSLT来完成。首先,您需要一个XSLT文档。下面的那个进行了您需要的转换(您可以测试它here):

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output indent="yes"/>
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"></xsl:apply-templates>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="year|gdppc|neighbor|country/text()" />
</xsl:stylesheet>

您可以使用LXML在Python中转换XSLT:

import lxml.etree as etree

source = etree.parse("data.xml")
xsldoc = etree.parse("stylesheet.xsl")
transform = etree.XSLT(xsldoc)
result = transform(source)
print(etree.tostring(result, pretty_print=True))

这种转变的结果是:

<?xml version="1.0" encoding="UTF-8"?>
<data>
    <country name="Liechtenstein">
      <rank>1</rank>
   </country>
    <country name="Singapore">
      <rank>4</rank>
   </country>
    <country name="Panama">
      <rank>68</rank>
   </country>
</data>

答案 1 :(得分:1)

一个简单的解决方案可能是删除所有不是datacountryrank的元素,然后输出根元素。

替代方法是创建一个带有data根的新文档,然后遍历所有rank元素,获取他们的直接父母,将他们作为子项复制到data(全部必要的属性)然后添加rank元素的副本。

但是由于elementtree没有保留父引用,因此需要一些解决方法:access ElementTree node parent node