【问题标题】:Python: how to get namespaces form xml?Python:如何从 xml 中获取命名空间?
【发布时间】:2021-04-23 09:24:36
【问题描述】:

W 想从大量带有命名空间的 xml 中提取一些数据。问题是每个 xml 中的名称空间可能不同,并且每个 xml 中都有几个。 Sample.xml 看起来像这样:

<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet type="text/xsl" href="http://some.domain/path1/styl.xsl"?>
<a:root xmlns:a="http://some.domain/path1/" xmlns:b="http://some.domain/path2/" xmlns:c="http://some.domain/path3/" xmlns:d="http://some.domain/path4/" xmlns:e="http://some.domain/path5/">
    <a:task>Get data from element your_data_sir in xml files</a:task>
    <a:files_to_process>More than 2k</a:files_to_process>
    <a:how>Using Python</a:how>
    <a:obstacle>
        <b:name>Namespaces</b:name>
        <c:description>Each xml file contain same xmlns:prefixes but the UIR of each prefix my differ!</c:description>
    </a:obstacle>
    <a:look_here>
        <d:your_data_sir>Glass of Whisky</d:your_data_sir>
        <d:your_data_sir>Cigar</d:your_data_sir>
        <d:your_data_sir>Python problem to solve</d:your_data_sir>
    </a:look_here>
    <e:other_things_to_know>
        <c:thing>Element look_here is allways a child of root element.</c:thing>
        <c:thing>look_here and your_data_sir preserve their prefixes in all xml files but URI can be different.</c:thing>
        <c:thing>Some xml files have different elements before and after look_here element.</c:thing>
        <c:thing>Number of siblings of look_here, before and after, may differ.</c:thing>
    </e:other_things_to_know>
</a:root>

我可以使用此脚本成功地从 元素获取数据:

import xml.etree.ElementTree as ET

ns = {
    'a': 'http://some.domain/path1/',
    'b': 'http://some.domain/path2/',
    'c': 'http://some.domain/path3/',
    'd': 'http://some.domain/path4/',
}

dom = ET.parse(Sample.xml).getroot()
test = dom.find('a:look_here', ns)

for x in test:
    print(x.text)

我正在构建脚本,它将使用上述脚本在文件夹和子文件夹中的每个 xml 文件上获取数据。问题是在某些 xml 文件中 xmlns:a (或其他前缀)中的 URI 可能不同。在这种情况下,我的脚本找不到 。我不知道也找不到从已处理的 xml 文件中获取所有前缀并构造名称空间字典的方法。或者也许有其他方法可以解决我的问题。

请帮忙。我是 python 新手,请您解释一下您的解决方案。

【问题讨论】:

  • 你能用 lxml 代替 ElementTree 吗? lxml 在元素上提供了一个方便的nsmap 属性:lxml.de/tutorial.html#namespaces
  • 感谢@mzjn 的评论。来自 lxml 的 nsmap 解决了我的问题。

标签: python xml-parsing namespaces


【解决方案1】:

感谢@mzjn,我设法解决了我的问题。现在看起来很简单。 lxml 有一个nsmap 属性,用于构建命名空间字典。您必须先安装 lxml,因为它默认不在 python 中。现在我的脚本如下所示:

from lxml import etree
dom = etree.parse('/path/to/Sample.xml').getroot()
ns = dom.nsmap
test = dom.find('a:look_here', ns)

for x in test:
    print(x.text)

在我的情况下,dom.nsmap 将返回 {'a': 'http://some.domain/path1/', 'b': 'http://some.domain/path2/', 'c': 'http://some.domain/path3/', 'd': 'http://some.domain/path4/', 'e': 'http://some.domain/path5/'} 这正是我过去两天一直在争取的。现在我可以向它提供数千个文件以从中获取数据,而不会丢失任何内容。

【讨论】:

    猜你喜欢
    • 2013-05-15
    • 2017-07-08
    • 1970-01-01
    • 2016-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-03
    相关资源
    最近更新 更多