基本 Python 使用 xml.etree 解析 XML - 问题

Basic Python Parsing XML with xml.etree - Issue

我正在尝试解析 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>

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

一旦你得到它,你必须使用 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 方法是否 returns None 并相应地处理错误。

请注意,尽管我对 xml 格式没有信心,但我通过遵循此 lxml tutorial.

了解了解析它的所有知识

results = root.findall("Results")xml.etree.ElementTree.Element objects 的 list

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

findfindall 只在 children 内查找。 iter 方法将遍历任何级别的匹配 sub-children。

选项 1

如果 <Results> 可能有多个 <Social> 元素,您可以使用:

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

这是最坏的情况。如果你知道每个 <Results> 会有一个 <Social> 那么它简化为:

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

两个return

"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 是列表的列表。外部列表包含 <Social> 个元素(本例中只有一个)
每个内部列表包含每个特定 <Social> 元素中的 v 个元素的文本。