2

これは、ElementTree を使用して XML を変更するための質問の続きです

XML に名前空間があり、「ElementTree」を介して Python で名前空間を使用して XML を解析するで答えを理解しようとしましたが、次のようになりました。

XML ファイル。

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 <grandParent>
  <parent>
   <child>Sam/Astronaut</child>
  </parent>
 </grandParent>
</project>

Parsing XML with namespace in Python via 'ElementTree' を見た後の私の python コード

import xml.etree.ElementTree as ET

spaces='xmlns':'http://maven.apache.org/POM/4.0.0','schemaLocation':'http://maven.apache.org/xsd/maven-4.0.0.xsd'}

tree = ET.parse("test.xml")
a=tree.find('parent')          
for b in a.findall('child', namespaces=spaces):
 if b.text.strip()=='Jay/Doctor':
    print "child exists"
    break
else:
    ET.SubElement(a,'child').text="Jay/Doctor"

tree.write("test.xml")

エラーが表示されます: AttributeError: 'NoneType' object has no attribute 'findall'

4

1 に答える 1

2

この行には 2 つの問題があります。

a=tree.find('parent')          

まず、<parent>ルート要素の直接の子ではありません。<parent>ルート要素の孫です。親へのパスは次のようになり/project/grandparent/parentます。を検索するに<parent>は、XPath 式を試す*/parentか、可能であればを試してください//parent

次に、デフォルトの名前空間に存在するため、単純な名前だけではアクセス<parent>できません。.find()名前空間を追加する必要があります。

次の 2 つの同等に有効な呼び出しは、それぞれがノードtree.find()を見つける必要があります。<parent>

a=tree.find('*/{http://maven.apache.org/POM/4.0.0}parent')
a=tree.find('*/xmlns:parent', namespaces=spaces)

次に、 への呼び出しにfindall()は名前空間修飾子が必要です。

for b in a.findall('xmlns:child', namespaces=spaces) 

第 4 に、新しい子要素を作成するための呼び出しには名前空間修飾子が必要です。ショートカット名を使用する方法があるかもしれませんが、見つけられませんでした。長い形式の名前を使用する必要がありました。

ET.SubElement(a,'{http://maven.apache.org/POM/4.0.0}child').text="Jay/Doctor"

最後に、デフォルトの名前空間を指定しない限り、XML 出力は見栄えが悪くなります。

tree.write('test.xml', default_namespace=spaces['xmlns'])

XML の側面とは関係なく、前の質問から私の回答を間違ってコピーしました。ではなく、と並んでいelseます:forif

for ...
  if ...
else ...
于 2014-07-31T23:16:41.820 に答える