web-dev-qa-db-ja.com

ElementTree(Python)のSubElementに属性を追加するにはどうすればよいですか?

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を介してアクセスでき、タグを読み取ることができます。

しかし、属性を追加しようとして失敗しました。

ここで別のスレッドで見つけた構文を使用してみました:(私の名前はc)

>>> 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を使用する必要がありますか? (これは好ましくないでしょう)?

7
sibert

これはあなたがやろうとしていることではありませんか? subiが要素であり、それにアクセスできると仮定すると、さらにElementTreeメソッドsetを使用できます。

subi.set(attr, value)

setElementTreeメソッドについてはこちらをご覧ください: https://docs.python.org/2/library/xml.etree.elementtree.html#xml.etree.ElementTree。 Element.set

13
German Petrov

キーワード引数を使用して、作成中に Element または SubElement の属性を指定できます。

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>

説明:

Element および SubElement のコンストラクターには、属性をキーワード引数として受け入れる**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">

Use .set を使用して、既存の要素に属性を追加することもできます。ただし、これは一度に1つの要素しか追加できません。 ( ドイツのペトロフによって提案された )。

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>
8
Stevoisiak