2014-01-31 48 views
2

我正在嘗試使用Python處理XML文件& xml.etree.ElementTree,並且存在多個「分層」默認名稱空間的問題。我需要做的是更改一些節點文本字段的內容,然後以相同的格式保存文件。Python,XML和多個「分層」默認名稱空間

也許一個例子文件將有助於講清楚......

這是我的代碼是什麼樣子:

from xml.etree import ElementTree 

ElementTree.register_namespace('pplv', 'whatever') 
ElementTree.register_namespace('', 'blah') # Register the default namespace 
parse_tree = ElementTree.parse(infile) 

for node in parse_tree.iter(): 
    if node.tag == '...': 
     node.text = '...' 
    if ... 

    parse_tree.write(outfile) 

這是我的源文件看起來像

<?xml version="1.0" encoding="UTF-8"?> 
<pplv:PPLVDocument xmlns:pplv="whatever"> 
    <pplv:node1>...</pplv:node1> 
    <pplv:node2>...</pplv:node2> 
    <pplv:node3 xmlns="blah"> 
    <node1>...</node1> 
    <node2>...</node2> 
    </pplv:node3> 
    <pplv:node4 xmlns="blah2"> 
    <node1>...</node1> 
    <node2>...</node2> 
    </pplv:node4> 
    <pplv:node5 xmlns="blah3"> 
    <node1>...</node1> 
    <node2>...</node2> 
    </pplv:node5> 
</pplv:PPLVDocument> 

當我使用ElementTree解析它時,註冊命名空間,我得到:

<?xml version="1.0" encoding="UTF-8"?> 
<pplv:PPLVDocument xmlns:pplv="whatever" xmlns="blah" xmlns:ns0="blah2" xmlns:ns1="blah3"> 
    <pplv:node1>...</pplv:node1> 
    <pplv:node2>...</pplv:node2> 
    <pplv:node3> 
    <node1>...</node1> 
    <node2>...</node2> 
    </pplv:node3> 
    <pplv:node4> 
    <ns0:node1>...</ns0:node1> 
    <ns0:node2>...</ns0:node2> 
    </pplv:node4> 
    <pplv:node5> 
    <ns1:node1>...</ns1:node1> 
    <ns1:node2>...</ns1:node2> 
    </pplv:node5> 
</pplv:PPLVDocument> 

如您所見,所有名稱空間定義已經「彙總」到一個節點中。在我的原始文檔中,默認名稱空間不斷得到重新定義(「blah」,「blah1」,「blah2」)。雖然我可以定義一個默認名稱空間(「blah」),但在這種情況下,在源文檔的不同點處定義了多個默認名稱空間; ElementTree似乎沒有辦法讓我在這個「形狀」中保存修改過的文件。

正如您大概猜測的那樣,使用這些文件的(現成的)代碼將不會接受我創建的文件,但可以與原始文件結構一起工作。

如果這會給我一種解決方法,很樂意切換到lxml;我只需要一個修復!

在此先感謝

回答

2

使用LXML:

>>> parser = etree.XMLParser(remove_blank_text=True) 
>>> root = etree.parse('in.xml', parser) 
>>> root.xpath('//pplv:node2/text()', namespaces={'pplv': 'whatever'}) 
['...'] 
>>> root.write('out.xml', pretty_print=True) 

$ cat out.xml 
<pplv:PPLVDocument xmlns:pplv="whatever"> 
    <pplv:node1>...</pplv:node1> 
    <pplv:node2>...</pplv:node2> 
    <pplv:node3 xmlns="blah"> 
    <node1>...</node1> 
    <node2>...</node2> 
    </pplv:node3> 
    <pplv:node4 xmlns="blah2"> 
    <node1>...</node1> 
    <node2>...</node2> 
    </pplv:node4> 
    <pplv:node5 xmlns="blah3"> 
    <node1>...</node1> 
    <node2>...</node2> 
    </pplv:node5> 
</pplv:PPLVDocument> 
+0

是的,完美的作品 - 非常感謝 – monch1962