使用Python的lxml包解析XML文件以获取完整标记

时间:2016-09-29 15:01:06

标签: python xml lxml

我有以下XML文件:

<root>

    <scene name="scene1">
        <view ath="0" atv="10"/>
        <image url="img1.jgp"/>
        <hotspot name="hot1"/>
    </scene>

    <scene name="scene2">
        <view ath="20" atv="10"/>
        <image url="img2.jgp"/>
        <hotspot name="hot2"/>
    </scene>

</root>

我正在使用lxml包编写Python脚本,以获取view中的整个scene1标记。那就是:

<view ath="0" atv="10" />

我已经阅读了lxml文档,但我能找到的只是如何获取标记,其属性或内容,而不是整个标记。

至少有人能指出我正确的方向吗? lxml是否有实现此功能的函数或方法?

谢谢,

拉斐尔

2 个答案:

答案 0 :(得分:1)

XML内容是这样的字符串:

content = u"""\
<root>

    <scene name="scene1">
        <view ath="0" atv="10"/>
        <image url="img1.jgp"/>
        <hotspot name="hot1"/>
    </scene>

    <scene name="scene2">
        <view ath="20" atv="10"/>
        <image url="img2.jgp"/>
        <hotspot name="hot2"/>
    </scene>

</root>
"""

您可以解析文件;但是,在这里,我解析了一个StringIO:

tree = etree.parse(io.StringIO(content))

所有内容都加载到ElementTree

要查找视图,我使用XPath表达式:

views = tree.xpath("//scene/view")

结果始终是一个列表:

for view in views:
    print(etree.tostring(view, with_tail=False))

你会得到:

<view ath="0" atv="10"/>
<view ath="20" atv="10"/>

答案 1 :(得分:0)

您给定的XML源包含一些错误;我解决了这些问题,请参阅下面的来源:

from lxml import etree

source = """
<root>
  <scene name="scene1">
    <view ath="0" atv="10" />
    <image url="img1.jgp" />
    <hotspot name="hot1" />
  </scene>

  <scene name="scene2">
    <view ath="20" atv="10" />
    <image url="img2.jgp" />
    <hotspot name="hot2" />
  </scene>
</root>
"""

要解析此来源,您将创建一个etree:

tree = etree.fromstring(source)

(对于来自文件的来源,请改用etree.parse()。)

现在,您可以通过正确访问tree来浏览已解析的XML。我最喜欢这样做的方法是使用XPath导航(掌握这些超出了你的问题范围):

allViews = tree.xpath('//root/scene/view')
for view in allViews:
  print view.attrib

这将打印XPath找到的每个视图标记的所有XML属性:

{'atv': '10', 'ath': '0'}
{'atv': '10', 'ath': '20'}

当然你也可以访问视图元素的其他属性,比如它们的嵌入文本(当然在这里是空的)或它们的子元素(子元素)(当然,在你的例子中,它们也没有子元素)。 / p>

您的问题的措辞表明您可能没有建立对这个view对象确实是“整个视图标记”这一事实的理解。您可以向view对象询问它由(view)构成的标记,其属性(见上文),其内容(view.text)及其子元素({{ 1}},但没有。)

您可以通过调用view.getchildren()将解析后的XML结构转换回ASCII表示形式;这将返回类似etree.tostring(view)的字符串。在大多数情况下,你不会这样做。

您还可以访问元素查看元素的子元素:

'<view ath="20" atv="10"/>\n    '

这将打印print tree.getchildren()[1].getchildren()[0].attrib 元素的第一个孩子(view)的第0个孩子(scene)的XML属性:

tree