【问题标题】:XML parse ignores textXML 解析忽略文本
【发布时间】:2019-06-09 08:41:14
【问题描述】:

我有以下问题,试图从 python 中的一堆 xml 文件中获取信息。我没有做任何特别的事情,例如:

import xml.etree.ElementTree as ET

root = ET.parse(r'C:\Documents\XMLfolder\file.xml').getroot()
info = root.find('foo').find('bar').find('info').text

这适用于我拥有的大部分信息 - 但 xml 的一部分采用以下格式:

<bar>
<info id="1"><label>1</label>SampleTextHere</info>
</bar>

上面的代码给出了None——不过,我可以找到info元素和label元素。我只是找不到文字。如果我编辑文件以删除&lt;label&gt; 1 &lt;/label&gt;,那么上面的代码将返回我需要的文本。

是否有一些我不知道的非常基本的东西可以让我在不修改所有 xml 文件以删除标签的情况下访问文本? (这是相关的)。

谢谢!

【问题讨论】:

标签: python xml python-3.x xml-parsing elementtree


【解决方案1】:

来自[Python 3]: xml.etree.ElementTree.Element.text强调是我的):

这些属性可用于保存与元素关联的附加数据。 它们的值通常是字符串,但也可以是任何特定于应用程序的对象。如果元素是从 XML 文件创建的,则 text 属性保存元素的开始标记与其第一个子标记或结束标记之间的文本,或 Nonetail em> 属性保存元素的结束标记和下一个标记之间的文本,或 None

...

要收集元素的内部文本,请参阅itertext(),例如"".join(element.itertext())

我根据您的规范创建了 3 个文件:

  • file0.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <root>
      <foo>
        <bar>
          <info id="1">SampleTextHere 0</info>
        </bar>
      </foo>
    </root>
    
  • file1.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <root>
      <foo>
        <bar>
          <info id="1"><label>LabelText</label>SampleTextHere 1</info>
        </bar>
      </foo>
    </root>
    
  • file2.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <root>
      <foo>
        <bar>
          <info id="1"></info>
        </bar>
      </foo>
    </root>
    

还有一些示例代码。

code.py

#!/usr/bin/env python3

import sys
import xml.etree.ElementTree as ET


def main():
    file_names = [
        "file0.xml",
        "file1.xml",
        "file2.xml",
    ]

    for file_name in file_names:
        root = ET.parse(file_name).getroot()
        info_node = root.find("foo").find("bar").find("info")
        text = info_node.text
        tail = info_node.tail
        iter_text = "".join(info_node.itertext())
        info_node_text = text or ""
        if not info_node_text:
            for info_node_text in info_node.itertext():
                pass
        print("\n{:s}\n      Text (for debugging purposes): [{:}]\n      Tail (for debugging purposes): [{:}]\n      Iter text (for debugging purposes): [{:s}]\n  Value: [{:s}]".format(
            file_name, text, tail, iter_text, info_node_text))


if __name__ == "__main__":
    print("Python {:s} on {:s}\n".format(sys.version, sys.platform))
    main() 

算法很简单:如果节点没有设置 text 属性,则遍历其 itertext() 并选择最后一个值,作为 label (或任何其他)子节点位于文本之前。

输出

(py_064_03.06.08_test0) e:\Work\Dev\StackOverflow\q054197111>"e:\Work\Dev\VEnvs\py_064_03.06.08_test0\Scripts\python.exe" code.py
Python 3.6.8 (tags/v3.6.8:3c6b436a57, Dec 24 2018, 00:16:47) [MSC v.1916 64 bit (AMD64)] on win32


file0.xml
      Text (for debugging purposes): [SampleTextHere 0]
      Tail (for debugging purposes): [
    ]
      Iter text (for debugging purposes): [SampleTextHere 0]
  Value: [SampleTextHere 0]

file1.xml
      Text (for debugging purposes): [None]
      Tail (for debugging purposes): [
    ]
      Iter text (for debugging purposes): [LabelTextSampleTextHere 1]
  Value: [SampleTextHere 1]

file2.xml
      Text (for debugging purposes): [None]
      Tail (for debugging purposes): [
    ]
      Iter text (for debugging purposes): []
  Value: []

【讨论】:

    猜你喜欢
    • 2011-01-09
    • 2023-03-22
    • 2012-01-29
    • 2015-11-07
    • 1970-01-01
    • 1970-01-01
    • 2022-06-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多