2016-04-09 14 views
0

私のXMLファイルから、各子ノードを別のファイルに書きたいと思っています。私はxml.etree.ElementTree.tostring(child_node)を使っています。私はすでにすべてのタグに "ns0:"を追加するのを避けるために.register_namespace()を使うべきであることを発見しました。しかし、私はまだ「のxmlnsは=」属性は、私が保存していますすべてのノードに追加しました:"xmlns ="を追加せずにXMLノード全体の内容を書き込む

ここでサンプルXMLファイルです:ここで

<?xml version="1.0" encoding="UTF-8"?> 
<kml xmlns="http://earth.google.com/kml/2.1"> 
<Document> 
<name>ref.kml</name> 
<Style id="normalState"> 
    <IconStyle><scale>1.0</scale><Icon><href>yt.png</href></Icon></IconStyle> 
    <BalloonStyle><text><![CDATA[$[description]]]></text></BalloonStyle>  
</Style> 
</Document> 
</kml> 

は私のコードです:

#!/usr/bin/env python 

import xml.etree.ElementTree as ET 

str_ns_url = 'http://earth.google.com/kml/2.1' 
ET.register_namespace('', str_ns_url) 

kml_file = ET.parse('my.kml') 
kml_doc = kml_file.getroot()[0] 

ndx = 0 
for child in kml_doc: 
    ndx+=1 
    f = open('node'+str(ndx)+'.txt','w') 
    f.write(ET.tostring(child)) 
    f.close() 

そして、これはあります最初のノード(<name>)のための出力:

<name xmlns="http://earth.google.com/kml/2.1">ref.kml</name> 

見ての通り、xmlns=はADDEましたdをタグに追加します。今のところ私はthis SO postしか見つけませんでしたが、基本的には.tostring()の後にその部分文字列を手動で削除することを提案しています。もっと良い解決策はありますか?多分ElementTree.tostring()の代わりに何か他のものを使うべきでしょうか?あなたが考慮する必要がありますどのような

答えて

1

は、ソースXML文書内の<name>要素が名前空間宣言なしのスタンドアロン要素<name>で考えられている一方で、それは、祖先要素<kml>から継承する名前空間http://earth.google.com/kml/2.1であるという事実であります空の名前空間。その<name>要素を抽出してそれを単独で印刷しようとすると、XMLプロセッサはの要素の意味を変更しないようにしようとします。名前空間宣言を要素selfでローカルに保持します。だからここで何をElementTree.tostring()が実際に期待される動作です。あなたは本当に名前空間が空に変更したい場合は、あなたが前tostring()を呼び出すには、名前空間を削除する要素のtagプロパティの名前を変更することができ、言っ

ns = "{http://earth.google.com/kml/2.1}" 
...... 
...... 
child.tag = child.tag.replace(ns, "") 
f.write(ET.tostring(child)) 

そして、印刷すべき要素が子孫を持っている場合要素の場合は、すべての子孫に対して同じ操作を行う必要があります。

for d in child.findall('.//*'): 
    d.tag = d.tag.replace(ns, "") 
関連する問題