python - 如何使用不同的层次结构解析xml并仅指定'name'

时间:2013-11-20 22:09:01

标签: python xml

我正在学习xml解析和Python,并尝试编写一个允许我只指定'name'的函数,它可以搜索我的xml并返回文本值。

目前,我的功能仅限于通过'GeneralSettings'进行搜索:

import xml.etree.ElementTree as ET

tree = ET.parse('template.xml')

    def getValues(tree, category):
        for prop_node in tree.iterfind("FileTemplate/properties/obj[@name='GeneralSettings']/properties/prop[@name='%s']" % category):
            return prop_node.text

    print getValues(tree, 'FilePattern')

有没有什么好的技巧我只能通过传入搜索'name'来编写一个函数,它可以自动搜索root下的所有内容,就像在unix中一样,'find。 -名称'?例如,如果我为“useelapsedtime”调用get text值,我可以使用相同的函数告诉它搜索name = useelapsedtime吗?

我的xml是这样的:

<?xml version="1.0" encoding="utf-8"?>
<autostart version="2.0">
<FileState>0</FileState>
<FileTemplate clsid="{6F6FBFC1-3F14-46CA-A269}">
<properties>
    <obj name="TypeSettings" clsid="{6F6FBFC1-3F14-46CA-A269}">
        <properties>
            <prop name="Enumerator" type="8">en0</prop>
            <prop name="Name" type="8">en0</prop>
            <prop name="Type" type="3">1</prop>
        </properties>
    </obj>
    <obj name="GeneralSettings" clsid="{6F6FBFC1-3F14-46CA-A269}">
        <properties>
            <prop name="BufferSize" type="21">524288000</prop>
            <prop name="FilePattern" type="8">auto_eth0</prop>
        </properties>
    </obj>
    <obj name="NiCSettings" clsid="{6F6FBFC1-3F14-46CA-A269}">
        <properties>
            <prop name="interface" type="21">eth0</prop>
        </properties>
    </obj>
    <obj name="Trigger" clsid="{E801FFF9-AE26-4DD7-A349">
        <trigger enabled="0" notify="1" severity="0" togglecapture="1">
            <triggerevents>
                <triggereventobj clsid="{EC5E8097-B3D5-4B8D-AA64}">
                    <triggerevent use="0" useelapsedtime="0" time="0" enabled="0" />
                </triggereventobj>
            </triggerevents>
        </trigger>
    </obj>
</properties>
   </FileTemplate>

1 个答案:

答案 0 :(得分:1)

是。使用tree.iterfind(".//*[@name='%s']"%name)

打破它:

tree是起始节点。在这种情况下,解析的根元素。

.表示XPATH描述以tree开头。

//意味着递归任意数量的级别

*表示考虑任何标记

[@name='foo']表示只考虑具有名为foo

的属性的元素

%s表示将变量的值替换为字符串

所以:

tree.iterfind(".//*[@name='%s']"%name)表示:

  • tree开始,
  • 并经历各个层面,
  • 查找任何元素,无论其标记名称如何,
  • ,其中包含名为name
  • 的属性
  • 哪个属性的值等于变量name的内容。