首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >解析python中的xml以获取所有子元素

解析python中的xml以获取所有子元素
EN

Stack Overflow用户
提问于 2018-07-03 20:51:36
回答 1查看 11.3K关注 0票数 0

我分析了一个XML文件以获取它的所有元素。我得到以下输出

代码语言:javascript
复制
[<Element '{urn:mitel:params:xml:ns:yang:vld}vld-list' at 0x0000000003059188>, <Element '{urn:mitel:params:xml:ns:yang:vld}vl-id' at 0x00000000030689F8>, <Element '{urn:mitel:params:xml:ns:yang:vld}descriptor-version' at 0x0000000003068A48>]

我需要为列表中的每个元素选择}和‘之间的值。

到目前为止,这是我的准则:

代码语言:javascript
复制
import xml.etree.ElementTree as ET  
tree = ET.parse('UMR_VLD01_OAM_V6-Provider_eth0.xml')  
root = tree.getroot()

# all items
print('\nAll item data:')
for elem in root:  
    all_descendants = list(elem.iter())
    print(all_descendants)

我怎样才能做到这一点?

EN

回答 1

Stack Overflow用户

发布于 2018-07-04 07:50:55

{}中的文本是XML元素的限定名(QName)的命名空间部分。在ElementTree中没有方法只返回本地名称。所以,你要么

  • 使用字符串处理提取名称的本地部分,正如在对您的问题的注释中所建议的那样,
  • 使用lxml.etree而不是xml.etree.ElementTree,并对每个元素应用xpath('local-name()')
  • 或者提供没有命名空间的XML源。您可以使用XSLT剥离命名空间。

因此,考虑到这个XML输入:

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<foo xmlns="urn:mitel:params:xml:ns:yang:vld">
    <bar>
        <baz x="1"/>
        <yet>
            <more>
                <nested/>
            </more>
        </yet>
    </bar>
    <bar/>
</foo>

只有在程序的这种变化下,才能打印本地名称的列表:

代码语言:javascript
复制
import xml.etree.ElementTree as ET  
tree = ET.parse('UMR_VLD01_OAM_V6-Provider_eth0.xml')  
root = tree.getroot()

# all items
print('\nAll item data:')
for elem in root:
    all_descendants = [e.tag.split('}', 1)[1] for e in elem.iter()]
    print(all_descendants)

输出:

代码语言:javascript
复制
['bar', 'baz', 'yet', 'more', 'nested']
['bar']

lxml.etreexpath('local-name()')的版本如下所示:

代码语言:javascript
复制
import lxml.etree as ET
tree = ET.parse('UMR_VLD01_OAM_V6-Provider_eth0.xml')  
root = tree.getroot()

# all items
print('\nAll item data:')
for elem in root:
    all_descendants = [e.xpath('local-name()') for e in elem.iter()]
    print(all_descendants)

输出与字符串处理版本相同。

为了从输入中完全去掉命名空间,可以应用以下XSLT:

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    <xsl:template match="*">
        <xsl:element name="{local-name()}">
            <xsl:copy-of select="@*"/>
            <xsl:apply-templates/>
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>

那么您的原始程序输出:

代码语言:javascript
复制
[<Element 'bar' at 0x04583B40>, <Element 'baz' at 0x04583B70>, <Element 'yet' at 0x04583BD0>, <Element 'more' at 0x04583C30>, <Element 'nested' at 0x04583C90>]
[<Element 'bar' at 0x04583CC0>]

现在,元素本身不包含名称空间。所以你不用再脱衣服了。

您可以使用xsltproc应用XSLT,然后不需要更改程序。或者,您可以使用将XSLT应用于python,但这也要求您使用lxml.etree。因此,您的程序的最后一个变体如下:

代码语言:javascript
复制
import lxml.etree as ET

tree = ET.parse('UMR_VLD01_OAM_V6-Provider_eth0.xml')  
xslt = ET.parse('stripns.xslt')
transform = ET.XSLT(xslt)
tree = transform(tree)

root = tree.getroot()
# all items
print('\nAll item data:')
for elem in root:
    all_descendants = list(elem.iter())
    print(all_descendants)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51162659

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档