【问题标题】:ElementTree - Issue in appending the subelement to an elementElementTree - 将子元素附加到元素的问题
【发布时间】:2018-08-01 06:46:44
【问题描述】:

我想在此处为该元素 country singapore 旁边的元素创建子元素。

假设我的 test.xml 文件如下所示

<?xml version="1.0" encoding="UTF-8"?>

<data>
    <country name="Malaysia" tst="bh">
        <year>2008</year>
        <gdppc>141100</gdppc>
        <neighbor name="Singapore" direction="E"/>
        <neighbor name="Switzerland" direction="W"/>
    </country>
    <district>
        <A name="test">
        </A>
    </district>
    <country name="Singapore" tst="ab">
        <rank updated="yes">5</rank>
        <year>2011</year>
        <gdppc>59900</gdppc>
        <neighbor name="Malaysia" direction="N"/>
    </country>
   <district>
        <B name="test">
        </B>
    </district>
</data>

在上面的例子中,我想为元素区创建子元素,但上面的元素应该是国家“新加坡”。 应该是

<district>
   <t1 name="t1>
   </t1>
     <B name="test">
    </B>
</district>

import xml.etree.ElementTree as et


tree = et.parse("test.xml")
root = tree.getroot()

country = root.find(".//country[@name='Singapore']")

et.subelement(country,"add new subelement")

我可以将子元素添加到国家元素。但是我不能在国家“新加坡”下面使用地区元素。

有人可以帮我吗?

【问题讨论】:

  • 您能否将预期的输出 xml 发布到问题中
  • 所以你想编辑district 元素,它最近的前兄弟是新加坡的country 元素?你能用 lxml 代替 ElementTree 吗? lxml 中的 XPath 支持要好得多。
  • 不,我不能使用 lxml

标签: python xpath elementtree


【解决方案1】:

这是如何使用 ElementTree 完成的。

import xml.etree.ElementTree as ET

root = ET.parse("country.xml").getroot()

# A list of all children of the root element (in document order)
children = list(root)

# Find the Singapore 'country' element
sing = root.find(".//country/[@name='Singapore']")

# Get the index of the 'country' element 
ix = children.index(sing)

# Find the wanted 'district' sibling element (position ix+1 in the list)
district = children[ix+1]

# Create a new 't1' element and add to 'district'
t1 = ET.Element("t1", name="t1")
district.insert(0, t1)

print(ET.tostring(root).decode("UTF-8"))

输出:

<data>
    <country name="Malaysia" tst="bh">
        <year>2008</year>
        <gdppc>141100</gdppc>
        <neighbor direction="E" name="Singapore" />
        <neighbor direction="W" name="Switzerland" />
    </country>
    <district>
        <A name="test">
        </A>
    </district>
    <country name="Singapore" tst="ab">
        <rank updated="yes">5</rank>
        <year>2011</year>
        <gdppc>59900</gdppc>
        <neighbor direction="N" name="Malaysia" />
    </country>
   <district>
        <t1 name="t1" /><B name="test">        <!-- New element added here --> 
        </B>
    </district>
</data>

【讨论】:

  • 使用lxml,可以使用XPath 直接定位所需的district 元素:district = root.xpath(".//district[preceding-sibling::country[1][@name='Singapore']]")[0]
【解决方案2】:

您尝试尝试的内容是不可能的,因为 XML 中不存在以下或以上内容。 XML 中的数据是无序的。如果你想在国家和地区之间建立关系,你可以在 District 元素中添加一个国家属性:

<?xml version="1.0" encoding="UTF-8"?>
<data>
    <country name="Malaysia" tst="bh">
        <year>2008</year>
        <gdppc>141100</gdppc>
        <neighbor name="Singapore" direction="E"/>
        <neighbor name="Switzerland" direction="W"/>
    </country>
    <district country="Malaysia">
        <A name="test">
        </A>
    </district>
    <country name="Singapore" tst="ab">
        <rank updated="yes">5</rank>
        <year>2011</year>
        <gdppc>59900</gdppc>
        <neighbor name="Malaysia" direction="N"/>
    </country>
   <district country="Singaporse">
        <B name="test">
        </B>
    </district>
</data>


import xml.etree.ElementTree as et    
tree = et.parse("test.xml")
root = tree.getroot()    
district = root.find(".//district[@country='Singapore']")    
et.subelement(district,"add new subelement")

或者使区元素成为国家元素的子元素:

<?xml version="1.0" encoding="UTF-8"?>
<data>
    <country name="Malaysia" tst="bh">
        <year>2008</year>
        <gdppc>141100</gdppc>
        <neighbor name="Singapore" direction="E"/>
        <neighbor name="Switzerland" direction="W"/>
        <district>
            <A name="test"/>
        </district>
    </country>
    <country name="Singapore" tst="ab">
        <rank updated="yes">5</rank>
        <year>2011</year>
        <gdppc>59900</gdppc>
        <neighbor name="Malaysia" direction="N"/>
        <district country="Singaporse">
            <B name="test"/>
        </district>
    </country>
</data>


import xml.etree.ElementTree as et    
tree = et.parse("test.xml")
root = tree.getroot()    
district = root.find(".//country[@name='Singapore']/district")    
et.subelement(district,"add new subelement")

编辑:添加 python 代码

【讨论】:

  • 我认为说“XML 中的数据是无序的”是一种误导。元素的顺序可能非常重要。见stackoverflow.com/q/1131495/407651
  • 这只是我给出的一个例子。我的方案基于国家和地区。我有有效的元素。而不是国家,可以说我有 A 元素和 B 元素而不是地区。如何做到这一点?
猜你喜欢
  • 2021-10-26
  • 1970-01-01
  • 2016-01-20
  • 2015-06-22
  • 1970-01-01
  • 1970-01-01
  • 2021-01-20
  • 2018-05-19
  • 2019-10-16
相关资源
最近更新 更多