【问题标题】:How do I add attributes to SubElement in ElementTree (Python)如何在 ElementTree (Python) 中向 SubElement 添加属性
【发布时间】:2014-11-06 13:56:59
【问题描述】:

我使用 PY 的 ElementTree 成功地将新节点添加到元素。 我现在尝试为它赋予属性,尽管我正在遵循教程,但它失败了。

我的示例 xml:

<?xml version="1.0" encoding="UTF-8"?>
<xml>
<level01>
<level02>
<level03>
<level04>
<node q="3,4,5,7,8" p="zen"/>
<node q="a,s,e,o,l" p="zen"/>
</level04>
</level03>
# >> here will be the new node, called <subi/> <<   
<level03>
<level04>
<node q="x,y" p="zen"/>
<node q="xxx,yyy" p="zen"/>
</level04>
</level03>
</level02>
</level01>
</xml>

节点是这样创建的:

subi = ETL.SubElement(root[0][0][1][0][0], 'subi')

哪个有效,然后可以通过root001000访问它,并且可以读取它的标签。

但我尝试添加属性失败。

我尝试使用我在另一个线程中找到的语法:(用我的名字 ofc)

>>> myattributes = {"size": "small", "gender": "unknown"}
>>> child = ET.SubElement(parent, "child", attrib=myattributes, age="10" )

我也直接试了,喜欢

subi = ETL.SubElement(root[0][0][1][0][0], 'subi', attrib={"size": "small", "gender": "unknown"})

结果总是

root[0][0][1][0][0][0].tag
'subi'

但是

root[0][0][1][0][0][0].attrib
{}

我还发现了 lxml 是如何做到的,但这不适用于 elementtree

#Any keyword arguments of the form name=value that you supply to the constructor are added #to the element's attributes. For example, this code:

newReed = etree.Element('reed', pitch='440', id='a4')

#will produce an element that looks like this:

<reed pitch='440' id='a4'/>

我做错了什么?我怎样才能做到正确?有没有办法让 elementtree 做到这一点?还是我必须使用lxml? (不推荐使用)?

【问题讨论】:

  • SubElement(parent,tag,attrib={name:key}) 语法对我来说很好用(Python 2.7.5)。您能否针对一个简短的两级 XML 文档、确切的插入代码和生成的 XML 输出提供一个示例?
  • 正如在下面的评论中发布的,我现在可以通过 doint subi.attrib 获得结果。不知何故,root[index].attrib 确实失败了......

标签: python attributes lxml elementtree


【解决方案1】:

这不是你想做的吗?假设subi是你的元素并且你可以访问它,你可以进一步使用ElementTree方法set

subi.set(attr, value)

看这里关于ElementTreeset方法:https://docs.python.org/2/library/xml.etree.elementtree.html#xml.etree.ElementTree.Element.set

【讨论】:

  • 设置属性值可以通过SubElement来完成。 OP 不应该在创建新元素后设置它们(尽管这也是可能的,当然)。
  • 我想我希望它在 SubElement 中完成,但 set 看起来也不错 - 在我的情况下,确切的语法是什么?如果我只是做 subi.set(xy, "3") 它将声明名称'xy'未定义
  • 你应该 subi.set("xy", "3") 它应该将 subi 标记为 &lt;subi xy="3"&gt;&lt;/subi&gt;
  • 好的,这行得通。奇怪的是,现在也显示了我之前尝试设置的属性。 root000101.attrib 不起作用而 subi.attrib 起作用有什么原因吗? (假设根索引拼写正确)
  • 很有趣,对我来说它工作正常:设置属性和值后,print tree[0][0][1][0][0][0].tag 给出subiprint tree[0][0][1][0][0][0].attrib 给出{'xy': '3'}
【解决方案2】:

您可以在创建过程中使用关键字参数为ElementSubElement 指定属性。

import xml.etree.ElementTree as ET

root = ET.Element('Summary')
ET.SubElement(root, 'TextSummary', Status='Completed')
# <Summary><TextSummary Status="Completed" /></Summary>

或者,您可以在创建后使用.set 向元素添加属性。

import xml.etree.ElementTree as ET

root = ET.Element('Summary')
sub = ET.SubElement(root, 'TextSummary')
sub.set('Status', 'Completed')
# <Summary><TextSummary Status="Completed" /></Summary>

生成的 XML:

<Summary>
    <TextSummary Status="Completed"/>
</Summary>

说明:

ElementSubElement 的构造函数包括**extra,它接受属性作为关键字参数。

xml.etree.ElementTree.Element(tag, attrib={}, **extra)
xml.etree.ElementTree.SubElement(parent, tag, attrib={}, **extra)

这允许您添加任意数量的属性。

root = ET.Element('Summary', Date='2018/07/02', Timestamp='11:44am')
# <Summary Date = "2018/07/02" Timestamp = "11:44am">

您还可以使用 .set 将属性添加到预先存在的元素。但是,这一次只能添加一个元素。 (Suggested by German Petrov)。

root = ET.Element('Summary')
root.set('Date', '2018/07/02')
root.set('Timestamp', '11:44am')
# <Summary Date = "2018/07/02" Timestamp = "11:44am">

完整示例:

import xml.etree.ElementTree as ET

root = ET.Element('school', name='Willow Creek High')
ET.SubElement(root, 'student', name='Jane Doe', grade='9')
print(ET.tostring(root).decode())
# <school name="Willow Creek High"><student grade="9" name="Jane Doe" /></school>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多