【问题标题】:How to extract values from xml file with namespaces?如何从带有命名空间的 xml 文件中提取值?
【发布时间】:2020-06-23 20:53:25
【问题描述】:

我有如下所示的 xml 文件,它有命名空间,我正在尝试提取 Node24 的值

我当前的代码如下,没有打印任何东西:

import xml.etree.ElementTree as ET

filename = 'ifile.xml'
tree = ET.parse(filename)
root = tree.getroot()

for neighbor in root.iter('Node24'):
    print(neighbor)

我的预期输出是:

03-c34ko
04-c64ko
07-c54ko  

就是ifile.xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<data-main-43:DATAMAINXZ123 xmlns="https://example.com/DATA-MAIN-XZ123" xmlns:data-gen="https://example.com/DATA-GEN" xmlns:data-main-43="https://example.com/DATA-MAIN-XZ123" xmlns:xsi="http://www.w3.org/2011/XMLSchema-instance" xsi:schemaLocation="https://example.com/DATA-MAIN-XZ123 data-main-ir21-12.1.xsd">
  <MAINXZ123FileHeader>
    <DATAGenSchemaVersion>2.4</DATAGenSchemaVersion>
    <DATAMAINXZ123SchemaVersion>12.1</DATAMAINXZ123SchemaVersion>
  </MAINXZ123FileHeader>
  <Node1>
    <Node2>WTRT DDK</Node2>
    <Node3>XYZW</Node3>
    <Node4>
      <Node5>
        <Node6>XYZW882</Node6>
        <Node5Type>Ter</Node5Type>
        <Node5Data>
          <Node9>
            <Node10>
              <Node11>2019-02-18</Node11>
              <Node12>
                <Node13>
                  <Node14>
                    <Node15>Ermso</Node15>
                    <Node16>
                      <PrimaryNode16>
                        <Node18>19.32</Node18>
                        <Node18>12.11</Node18>
                      </PrimaryNode16>
                      <SecondaryNode16>
                        <Node18>82.97</Node18>
                        <Node18>12.41</Node18>
                      </SecondaryNode16>
                    </Node16>
                    <Node20>Muuatippw</Node20>
                  </Node14>
                </Node13>
              </Node12>
              <Node21>
                <Node22>
                  <Node23>
                    <Node24>03-c34ko</Node24>
                    <Node24>04-c64ko</Node24>
                    <Node24>07-c54ko</Node24>
                  </Node23>
                  <Node26Node22EdgeAgent>
                    <Node26>jjkksonem</Node26>
                    <PrimaryNode18DEANode26>
                      <Node18>2.40</Node18>
                    </PrimaryNode18DEANode26>
                  </Node26Node22EdgeAgent>
                </Node22>
              </Node21>
              <Node28>
                <Node29>
                  <Node30>false</Node30>
                  <Node31>true</Node31>
                </Node29>
              </Node28>
            </Node10>
          </Node9>
        </Node5Data>
      </Node5>
    </Node4>
  </Node1>
</data-main-43:DATAMAINXZ123>

我该怎么做?提前致谢。

【问题讨论】:

标签: python xml xml-parsing xml-namespaces elementtree


【解决方案1】:

duplicate mzjn referenced一样,只需将命名空间uri添加到元素名称...

import xml.etree.ElementTree as ET

filename = 'ifile.xml'
tree = ET.parse(filename)
root = tree.getroot()

for neighbor in root.iter('{https://example.com/DATA-MAIN-XZ123}Node24'):
    print(neighbor.text)

注意:我还将.text 添加到neighbor,这样您就可以得到请求的结果。

【讨论】:

    【解决方案2】:

    我正在使用正则表达式,所以这是一个替代答案。 我将 xml 转换为字符串,然后搜索 Node24 之间的所有字符串

    import xml.etree.ElementTree as ET
    import re
    
    filename = 'ifile.xml'
    tree = ET.parse(filename)
    root = tree.getroot()
    xml_str = ET.tostring(root) 
    for s in re.findall(r'ns0:Node24>(.*?)</ns0:Node24', str(xml_str)):
        print(s)
    

    结果:

    03-c34ko
    04-c64ko
    07-c54ko
    

    【讨论】:

    • 感谢您的帮助。它似乎工作。但是如果我想提取更多元素,我需要更改正则表达式中的节点吗?另一个问题,ns0:... 是什么意思?
    • 当您可以只使用open("ifile.xml").read() 并假装没有默认命名空间时,为什么还要麻烦解析为 XML?在大多数情况下,在 XML 或 HTML 上使用正则表达式并不是一个好主意。 stackoverflow.com/q/1732348/407651
    • @mzjn 我不明白你的意思,呵呵。您建议如何提取Node24 的值?如果正则表达式不是一个好主意...
    • @mzjn 我看到了。在那个链接中,他们谈到使用正则表达式解析不好,该线程中的其他人说“不要听这些人的”,但我的问题没有解决方案。
    猜你喜欢
    • 1970-01-01
    • 2017-09-27
    • 2012-04-28
    • 2013-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-27
    • 2014-06-05
    相关资源
    最近更新 更多