0

我正在解析一个 xml 文件: http: //pastebin.com/fw151jQN我希望读取它并将其中的一些复制到一个新文件中。我不确定这有多容易?我目前可以使用以下代码复制整个文件:

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

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

我可以这样写节点吗?

编辑以显示更改文本

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
4

1 回答 1

2

(1) 您无法从 ElementTree 获得完全所需的输出,因为您要求的 XML 格式不正确。要么将节点包装<COMMAND>到根标签中,要么将片段一个一个序列化并连接起来。

(2) 是的,XPath 表达式搜索的实现是合理的。在您的情况下,您必须在搜索时指定名称空间。对根元素下的元素进行简单扫描也可能就足够了。

我的看法:

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
于 2013-07-02T14:38:05.693 回答