如何在ElementTree(Python)中向SubElement添加属性

sib*_*ert 6 python attributes lxml elementtree

我使用PY的ElementTree成功地向Element添加了一个新节点.我现在尝试给它属性,但是失败了,尽管我正在按照教程进行操作.

我的例子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>
Run Code Online (Sandbox Code Playgroud)

节点的创建方式如下:

subi = ETL.SubElement(root[0][0][1][0][0], 'subi')
Run Code Online (Sandbox Code Playgroud)

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

但我没有尝试添加属性.

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

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

我也直接尝试过,比如说

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

结果总是如此

root[0][0][1][0][0][0].tag
'subi'
Run Code Online (Sandbox Code Playgroud)

root[0][0][1][0][0][0].attrib
{}
Run Code Online (Sandbox Code Playgroud)

我也发现了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'/>
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?我该怎么办?有没有办法让elementtree做到这一点?或者我必须使用lxml?(这将是不受欢迎的)?

小智 12

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

subi.set(attr, value)
Run Code Online (Sandbox Code Playgroud)

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


Ste*_*ica 5

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

import xml.etree.ElementTree as ET

root = ET.Element('Summary')
ET.SubElement(root, 'TextSummary', Status='Completed')
# <Summary><TextSummary Status="Completed" /></Summary>
Run Code Online (Sandbox Code Playgroud)

或者,您可以.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>
Run Code Online (Sandbox Code Playgroud)

生成的XML:

import xml.etree.ElementTree as ET

root = ET.Element('Summary')
ET.SubElement(root, 'TextSummary', Status='Completed')
# <Summary><TextSummary Status="Completed" /></Summary>
Run Code Online (Sandbox Code Playgroud)

说明:

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

xml.etree.ElementTree.Element(tag, attrib={}, **extra)
xml.etree.ElementTree.SubElement(parent, tag, attrib={}, **extra)
Run Code Online (Sandbox Code Playgroud)

这使您可以添加任意数量的属性。

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

您还可以使用use .set将属性添加到预先存在的元素中。但是,一次只能添加一个元素。(由德国彼得罗夫建议)。

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

完整示例:

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>
Run Code Online (Sandbox Code Playgroud)