2013-07-02 46 views
0

我正在解析一个xml文件:http://pastebin.com/fw151jQN我希望将它读入并将其复制到新文件中。我不确定这是多么容易?我目前可以将整个文件使用此代码复制:将xml文件的一部分写入新文件,elementree

import xml.etree.ElementTree as ET 
tree = ET.parse('interface_range_test.xml') 
root = tree.getroot() 
tree.write('new_file.xml', encoding="utf-8", xml_declaration=True) 

有没有一种方法来搜索和写入某些元素到一个新的文件吗?

起初我希望创建一个只包含以下内容作为试运行的新文件:

<COMMAND name="shutdown" 
     help="Shutdown the selected interface"> 
     <CONFIG priority="0x7F01" /> 
     <ACTION> 
     /klas/klish-scripts/interfaces.py conf -i ${iface} --enable 0 
     </ACTION> 
    </COMMAND> 

    <COMMAND name="no shutdown" 
     help="Enable the selected interface"> 
     <CONFIG operation="unset" pattern="shutdown"/> 
     <ACTION> 
     /klas/klish-scripts/interfaces.py conf -i ${iface} --enable 1 
     </ACTION> 
    </COMMAND> 

另一种方式可能是隔离的必要信息,并形成从它的元素?这里是我尝试隔离上面的xml:

import xml.etree.ElementTree as ET 
tree = ET.parse('interface_range_test.xml') 
root = tree.getroot() 
namespaces = {'command': 'http://clish.sourceforge.net/XMLSchema}COMMAND','config': 'http://clish.sourceforge.net/XMLSchema}CONFIG'} 

commands = root.findall(".//{http://clish.sourceforge.net/XMLSchema}COMMAND") 

for command in commands: 
    subs = command.findall('.//{http://clish.sourceforge.net/XMLSchema}CONFIG') 
    action = command.findall('.//{http://clish.sourceforge.net/XMLSchema}ACTION') 

    if len(subs) > 0: #we found CONFIG 
     print command.tag 
     #print command.attrib['name'] 
     #print command.attrib.keys(),command.attrib.values() 
     b = command.attrib.items() 
     print b 
     print subs[0].tag 
     c = subs[0].attrib.items() 
     print c 
    if len(action) > 0: #we found ACTION 
     print action[0].tag 
     print action[0].attrib 
     print action[0].text 

这获得所有相关信息,但也获得一些额外的行动标签及其文本。

{http://clish.sourceforge.net/XMLSchema}ACTION 
{'builtin': 'clish_nested_up'} 
None 
{http://clish.sourceforge.net/XMLSchema}ACTION 
{} 

/klas/klish-scripts/ifrange.py validate_range --range "${interface_method} ${iface_num} ${range_separator} ${iface_num2} ${range_separator2} ${interface_method2} ${iface_num3} ${range_separator3} ${iface_num4} ${range_separator4} ${interface_method3} ${iface_num5} ${range_separator5} ${iface_num6} ${range_separator6} ${interface_method4} ${iface_num7} ${range_separator7} ${iface_num8}" 

if [[ $? -eq 0 ]]; then 
/klas/klish-scripts/ifrange.py run_command --cmdrange "${interface_method} ${iface_num} ${range_separator} ${iface_num2} ${range_separator2} ${interface_method2} ${iface_num3} ${range_separator3} ${iface_num4} ${range_separator4} ${interface_method3} ${iface_num5} ${range_separator5} ${iface_num6} ${range_separator6} ${interface_method4} ${iface_num7} ${range_separator7} ${iface_num8}" --command "/klas/klish-scripts/interfaces.py conf -i {iface} --enable 0" --klish_config "shutdown" --klish_action "set" --priority "0x7F01" 
fi 





{http://clish.sourceforge.net/XMLSchema}COMMAND 
[('name', 'shutdown'), ('help', 'Shutdown the selected interface')] 
{http://clish.sourceforge.net/XMLSchema}CONFIG 
[('priority', '0x7F01')] 
{http://clish.sourceforge.net/XMLSchema}ACTION 
{} 

     /klas/klish-scripts/interfaces.py conf -i ${iface} --enable 0 

{http://clish.sourceforge.net/XMLSchema}COMMAND 
[('name', 'no shutdown'), ('help', 'Enable the selected interface')] 
{http://clish.sourceforge.net/XMLSchema}CONFIG 
[('pattern', 'shutdown'), ('operation', 'unset')] 
{http://clish.sourceforge.net/XMLSchema}ACTION 
{} 

     /klas/klish-scripts/interfaces.py conf -i ${iface} --enable 1 

我可以尝试使用找到的数据来创建输出吗?这是做这件事的好方法吗?或者,有没有比试图搜索每一条数据更好的方法?也许获得节点,然后是孙子?然而,我似乎无法完成这项工作。或者找到关闭元素并将其全部写入,并将它写入文件中?

我可以写这样的节点吗?

EDIT显示更改文本

for command in commands: 
    if 'shutdown' in command.get('name'): 
     for i in command: 
      i.text = "abc" #modify to taste 

     ET.dump(command) # modify to taste 

回答

2

(1)你不能得到准确的ElementTree中所需的输出,因为你问一个没有良好的XML。将<COMMAND>节点换成根标签,或者逐个序列化片段并连接。 (2)是的,有reasonable implementation of search by XPath expressions。在你的情况下,你必须在搜索时指定命名空间。根元素下的元素的简单扫描也可能足够。

我的看法:

import xml.etree.ElementTree as ET 
tree = ET.parse('interface_range_test.xml') 
root = tree.getroot() 
# note the explicit namespaces 
commands = root.findall('{http://clish.sourceforge.net/XMLSchema}' 
         'VIEW/{http://clish.sourceforge.net/XMLSchema}COMMAND') 
for command in commands: 
    if 'shutdown' in command.get('name'): 
    ET.dump(command) # modify to taste 
+0

很大的帮助谢谢。当你说完全相同的输出时,你的意思是什么?你生成的输出看起来很好,我想要的格式(我认为它ns0不会影响文件,为什么它会写这个?)所以基本上我一个接一个地寻找我想要的东西并连接到一个文件?既然它说'转储'只用于调试,我该如何写命令文件?它说元素没有写功能。再次感谢。 – Paul

+0

我试图修改文本,但我不知道这是否是一种好方法,将其编辑到我的文章中。这似乎可以,现在我只需要把它放到一个文件中。 – Paul

+0

@Paul:阅读[文档](http://docs.python.org/2/library/xml.etree.elementtree.html#xml.etree.ElementTree.tostring)帮助,因为他们告诉你如何写一个子树到一个字符串。从这一点,你[很可能](http://docs.python.org/2/library/stdtypes.html#file.write)。 – 9000