2014-01-31 2 views
2

Я пытаюсь обработать файл XML с помощью Python & 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> 

Как вы можете видеть, все определения пространства имен были «свернуты» в один узел. В моем исходном документе пространство имен по умолчанию продолжает пересматриваться («бла», «blah1», «blah2»). Хотя я могу определить одно пространство имен по умолчанию («бла»), в этом случае существует несколько пространств имен по умолчанию, определенных в исходном документе в разных точках; 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

Дa, отлично работает - спасибо очень много – monch1962

Смежные вопросы