[英]How to output Multiple elements from an XML with the same name using Python?
[英]How to remove elements from XML using Python
我厭倦了XML和Python。 任務很簡單,但到目前為止我無法解決它並花了很長時間。 我來這里是為了建議如何用幾行來解決它。
感謝您遍歷樹的任何幫助。 我總是得到太多或太少的元素。 元素可以無限制地嵌套。 舉個例子就是一個例子。 我會接受任何解決方案,而不是挑剔dom,minidom,sax,等等......
我有一個類似於這個的XML文件:
<root>
<elm>
<elm>Common content</elm>
<elm xmlns="http://example.org/ns">
<elm lang="en">Content EN</elm>
<elm lang="cs">žluťoučký koníček</elm>
</elm>
<elm xml:id="abc123">Common content</elm>
<elm lang="en">Content EN</elm>
<elm lang="cs">Content CS</elm>
<elm lang="en">
<elm>Content EN</elm>
<elm>Content EN</elm>
</elm>
<elm lang="cs">
<elm>Content CS</elm>
<elm>Content CS</elm>
</elm>
</elm>
</root>
我需要的 - 解析XML並編寫一個新文件。 新文件應包含給定語言的所有元素和沒有lang
屬性的元素。
對於“cs”語言,輸出文件應包含以下內容:
<root>
<elm>
<elm>Common content</elm>
<elm xmlns="http://example.org/ns">
<elm lang="cs">žluťoučký koníček</elm>
</elm>
<elm xml:id="abc123">Common content</elm>
<elm lang="cs">Content CS</elm>
<elm lang="cs">
<elm>Content CS</elm>
<elm>Content CS</elm>
</elm>
</elm>
</root>
如果你可以在新文件中省略lang
屬性,那就更好了。 但它並不重要。
UPDATE1:添加了unicode字符和名稱空間屬性。
UPDATE2:使用Python 2.5,首選標准庫。
使用lxml :
import lxml.etree as le
with open('doc.xml','r') as f:
doc=le.parse(f)
for elem in doc.xpath('//*[attribute::lang]'):
if elem.attrib['lang']=='en':
elem.attrib.pop('lang')
else:
parent=elem.getparent()
parent.remove(elem)
print(le.tostring(doc))
產量
<root>
<elm>Common content</elm>
<elm>
<elm>Content EN</elm>
</elm>
<elm>Common content</elm>
<elm>Content EN</elm>
<elm>
<elm>Content EN</elm>
<elm>Content EN</elm>
</elm>
</root>
我不確定如何最好地刪除lang
屬性,但是這里有一些代碼可以執行其他更改(Python 2.7;對於2.5或2.6,使用getIterator
而不是iter
),假設當您刪除元素時,您也總是希望刪除該元素中包含的所有內容。
此代碼只是將結果打印到標准輸出(您可以根據需要重定向它,當然,或直接將其寫入某個新文件,依此類推):
import sys
from xml.etree import cElementTree as et
def picklang(path, lang='en'):
tr = et.parse(path)
for element in tr.iter():
for subelement in element:
la = subelement.get('lang')
if la is not None and la != lang:
element.remove(subelement)
return tr
if __name__ == '__main__':
tr = picklang('la.xml')
tr.write(sys.stdout)
print
以la.xml
為例,這寫道
<root>
<elm>Common content</elm>
<elm>
<elm lang="en">Content EN</elm>
</elm>
<elm>Common content</elm>
<elm lang="en">Content EN</elm>
<elm lang="en">
<elm>Content EN</elm>
<elm>Content EN</elm>
</elm>
</root>
更新@Alex Martelli的代碼,以刪除元素列表更新到位的錯誤。 如果輸入稍微復雜,上述解決方案將給出錯誤的答案。
import sys
from xml.etree import cElementTree as et
def picklang(path, lang='en'):
tr = et.parse(path)
for element in tr.iter():
for subelement in element[:]:
la = subelement.get('lang')
if la is not None and la != lang:
element.remove(subelement)
return tr
if __name__ == '__main__':
tr = picklang('la.xml')
tr.write(sys.stdout)
print
第7行for subelement in element:
代碼for subelement in element:
更改for subelement in element[:]:
因為在迭代時更新列表是不正確的。
此代碼迭代元素列表的副本,並在原始元素列表中的lang!=“en”時刪除元素。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.