【问题标题】:Basic Python Parsing XML with xml.etree - Issue使用 xml.etree 解析 XML 的基本 Python - 问题
【发布时间】:2017-05-12 04:42:52
【问题描述】:

我正在尝试解析 XML,但很难做到。我不明白为什么结果一直打印[<Element 'Results' at 0x105fc6110>] 我正在尝试使用

从我的示例中提取 Social
import xml.etree.ElementTree as ET
root = ET.parse("test.xml")
results = root.findall("Results")
print results #[<Element 'Results' at 0x105fc6110>]
              # WHAT IS THIS??


for result in results:
    print result.find("Social") #None

XML 看起来像这样:

<?xml version="1.0"?>
<List1>
    <NextOffset>AAA</NextOffset>
    <Results>
        <R>
            <D>internet.com</D>
            <META>
                <Social>
                    <v>http://twitter.com/internet</v>
                    <v>http://facebook.com/internet</v>
                </Social>
                <Telephones>
                    <v>+1-555-555-6767</v>
                </Telephones>
            </META>
        </R>
    </Results>
</List1>

【问题讨论】:

    标签: python xml lxml elementtree minidom


    【解决方案1】:

    findall 返回 listxml.etree.ElementTree.Element 对象。在您的情况下,您只有 1 个 Result 节点,因此您可以使用 find 来查找第一个/唯一匹配项。

    一旦你得到它,你必须使用find 使用.// 语法,它允许在树中的任何地方搜索,而不仅仅是直接在Result 下的那个。

    找到后,只需在 v 标签上的 findall 并打印文本:

    import xml.etree.ElementTree as ET
    root = ET.parse("test.xml")
    result = root.find("Results")
    
    social = result.find(".//Social")
    
    for r in social.findall("v"):
        print(r.text)
    

    结果:

    http://twitter.com/internet
    http://facebook.com/internet
    

    请注意,我没有对 xml 文件执行有效性检查。您应该检查find 方法是否返回None 并相应地处理错误。

    请注意,尽管我对 xml 格式没有信心,但我通过遵循 lxml tutorial 了解了解析它的所有知识。

    【讨论】:

    • 具体来说,您的问题是没有路径表达式,findallfind 仅搜索节点的子节点,而不是节点的所有后代。 Results 是根元素 List1 的子元素,因此您的第一个 findall 找到了它,但 Social 不是 Results 的子元素,因此 find 在按名称搜索时找不到它。
    【解决方案2】:

    results = root.findall("Results")listxml.etree.ElementTree.Element 对象。

    type(results)
    # list
    type(results[0])
    # xml.etree.ElementTree.Element
    

    findfindall 仅在 first 个子项中查找。 iter 方法将遍历匹配任何级别的子子项。

    选项 1

    如果&lt;Results&gt; 可能有多个&lt;Social&gt; 元素,您可以使用这个:

    for result in results:
        for soc in result.iter("Social"):
            for link in soc.iter("v"):
                print link.text
    

    这是最坏的情况。如果您知道每个&lt;Results&gt; 会有一个&lt;Social&gt;,那么它可以简化为:

    for soc in root.iter("Social"):
        for link in soc.iter("v"):
            print link.text
    

    都返回

    "http://twitter.com/internet"
    "http://facebook.com/internet"
    

    选项 2

    或者使用嵌套列表推导并使用一行代码来完成。因为 Python...

    socialLinks = [[v.text for v in soc] for soc in root.iter("Social")]
    
    # socialLinks == [['http://twitter.com/internet', 'http://facebook.com/internet']]
    

    socialLinks 是列表列表。外部列表包含&lt;Social&gt; 元素(本例中只有一个)
    每个内部列表都包含来自每个特定&lt;Social&gt; 元素中v 元素的文本。

    【讨论】:

    • 好。我必须对其进行测试,因为我不确定iter 是否足够深入。确实如此。不错。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-26
    • 2020-11-02
    • 2011-09-05
    • 1970-01-01
    相关资源
    最近更新 更多