当前位置: 首页 > 知识库问答 >
问题:

ElementTree:解析XML曾孙[重复]

徐奇
2023-03-14

我已经尝试解析一些XML好几个小时了,但运气不好。检查了类似的线程并查看了ElementTree文档,但仍然很失落。

基本上,我从路由器接收到一些XML输出,这些输出存储在一个字符串中,然后我必须对其进行解析,以获得一些特定的信息。

下面是我正在研究的xml示例:

xml = """<rpc-reply xmlns:junos="http://xml.juniper.net/junos/14.1D0/junos">
        <route-information xmlns="http://xml.juniper.net/junos/14.1D0/junos-routing">
            <!-- keepalive -->
            <route-table>
                <table-name>inet.0</table-name>
                <destination-count>52</destination-count>
                <total-route-count>52</total-route-count>
                <active-route-count>52</active-route-count>
                <holddown-route-count>0</holddown-route-count>
                <hidden-route-count>0</hidden-route-count>
                <rt junos:style="brief">
                    <rt-destination>5.5.5.5/32</rt-destination>
                    <rt-entry>
                        <active-tag>*</active-tag>
                        <current-active/>
                        <last-active/>
                        <protocol-name>Direct</protocol-name>
                        <preference>0</preference>
                        <age junos:seconds="428929">4d 23:08:49</age>
                        <nh>
                            <selected-next-hop/>
                            <via>lo0.0</via>
                        </nh>
                    </rt-entry>
                </rt>
            </route-table>
        </route-information>
        <cli>
            <banner></banner>
        </cli>
</rpc-reply>"""

例如,我想要获取/打印内容的节点是rt目的地。

我试过:

root = ET.fromstring(xml)

values = root.find('rt')
for element in values:
    print element.text

这个,

value= root.find('rt-destination')

print value

这是设置根(指针?)在特定节点上,

x = root.getiterator(tag = "destination-count")

关于如何遍历到此特定节点或如何获得所需结果的任何帮助都将非常感谢。

共有2个答案

马德宇
2023-03-14

代码不起作用的原因是名称空间。如果命名空间始终相同,则可以将其编码为要查找的标记的前缀:

import xml.etree.ElementTree as ET

xml = """
<rpc-reply xmlns:junos="http://xml.juniper.net/junos/14.1D0/junos">
    <route-information xmlns="http://xml.juniper.net/junos/14.1D0/junos-routing">
        <!-- keepalive -->
        <route-table>
            <table-name>inet.0</table-name>
            <destination-count>52</destination-count>
            <total-route-count>52</total-route-count>
            <active-route-count>52</active-route-count>
            <holddown-route-count>0</holddown-route-count>
            <hidden-route-count>0</hidden-route-count>
            <rt junos:style="brief">
                <rt-destination>5.5.5.5/32</rt-destination>
                <rt-entry>
                    <active-tag>*</active-tag>
                    <current-active/>
                    <last-active/>
                    <protocol-name>Direct</protocol-name>
                    <preference>0</preference>
                    <age junos:seconds="428929">4d 23:08:49</age>
                    <nh>
                        <selected-next-hop/>
                        <via>lo0.0</via>
                    </nh>
                </rt-entry>
            </rt>
        </route-table>
    </route-information>
    <cli>
        <banner></banner>
    </cli>
</rpc-reply>
"""

XML_NAMESPACE = '{http://xml.juniper.net/junos/14.1D0/junos-routing}'
root = ET.fromstring(xml)
rt_nodes = root.iter(tag='{}rt-destination'.format(XML_NAMESPACE))
print rt_nodes.next().text  # 5.5.5.5/32

如果你需要更灵活的方式,你可以在这里查看答案。

卫嘉佑
2023-03-14

您缺少路由信息标记的命名空间。在XML中有两个名称空间,不幸的是,您需要的名称空间没有标记。

<rpc-reply xmlns:junos="http://xml.juniper.net/junos/14.1D0/junos">
    <route-information xmlns="http://xml.juniper.net/junos/14.1D0/junos-routing">

rpc-回复属于命名空间junos,然而,下一层及其下的所有内容都属于未命名(空)命名空间xmlns="http://xml.juniper.net/junos/14.1D0/junos-routing"

使用root.nsmap为根层提供以下命名空间字典:{'junos':'http://xml.juniper.net/junos/14.1D0/junos'}。因此,要访问此命名空间中的rt元素,您将使用:

root.find('junos:rt', namespaces=root.nsmap)

然而,在下一层lxml.etree知道命名空间"http://xml.juniper.net/junos/14.1D0/junos-routing",但是因为它没有标签,所以它将其提取到命名空间映射中字典键。

>>> nsmap = root.getchildren()[0].nsmap
>>> nsmap
{'junos': 'http://xml.juniper.net/junos/14.1D0/junos',
 None: 'http://xml.juniper.net/junos/14.1D0/junos-routing'}

这是一个问题,因为我们不能使用None引用名称空间。一种选择是只在字典中为创建一个新的名称空间引用http://xml.juniper.net/junos/14.1D0/junos-routing“

nsmap['my_ns'] = nsmap.pop(None)

我们需要在这里使用. pop,因为lxml不允许使用以为键的命名空间。现在,您可以使用xpath搜索rt-目的地标记,并仅返回标记中的文本。

root.xpath('.//my_ns:rt-destination/text()', namespaces=nsmap)
 类似资料:
  • 我有一个动态生成的树视图。我的问题是,它添加相同的节点-它从另一个应用程序接收列表,虽然其中相同的项目是重复的,但我不想在我的树视图中包括重复的项目。我试图避免在第一种情况下添加节点;但是失败了。我检查是否存在的代码如下(尝试了一些): 和

  • 本文向大家介绍Python中使用ElementTree解析XML示例,包括了Python中使用ElementTree解析XML示例的使用技巧和注意事项,需要的朋友参考一下 【XML基本概念介绍】 XML 指可扩展标记语言(eXtensible Markup Language)。 XML 被设计用来传输和存储数据。 概念一: 概念二: 概念三: 概念四: 概念五: 概念六: 【XML几种解析方法】

  • 问题内容: 我很难找到一个很好的基本示例,说明如何使用元素树在python中解析XML。据我所知,这似乎是用于解析XML的最简单的库。这是我正在使用的XML的示例: 我可以使用硬编码的方法来做我需要的事情。但是我需要我的代码更具动态性。这是起作用的: 这是我尝试过的几件事,但都没有奏效,报告他们找不到timeSeries(或我尝试过的其他任何东西): 基本上,我想加载xml文件,搜索timeSer

  • 问题内容: 我正在尝试将以下feed解析为python中的ElementTree:“ http://smarkets.s3.amazonaws.com/oddsfeed.xml ”(警告大文件) 到目前为止,这是我尝试过的: 但是它似乎只是挂在上面,也许是无限地??(我知道这是一个大文件,但与我解析的其他非压缩提要相比似乎太长了,而这个大文件首先会扼杀gzip压缩带来的任何带宽增长)。 接下来我尝

  • 问题内容: 我有一组要解析的超简单XML文件…但是…它们使用自定义定义的实体。我不需要将它们映射到字符,但是我确实希望对每个字符进行解析和操作。例如: 在http://effbot.org/elementtree/elementtree- xmlparser.htm 上有一个诱人的提示,即XMLParser对实体的支持有限,但是我找不到所提到的方法,所有的东西都会出错: 取决于您如何调整注释而得出

  • 问题内容: 当前使用Python 2.4.3,并且不允许升级 我想更改一个或多个标记中给定属性的值,以及更新文件中的XML注释。 我设法创建了一个以XML文件作为参数的Python脚本,并且为每个指定的标签更改了一个属性,如下所示 一切都很好,属性“ initialState”已更新,除了我的原始XML也包含许多XML注释的事实,但它们早已消失了,这是不好的。 怀疑只能解析XML结构,但我认为XM