Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用pythonlxml处理嵌套元素_Python_Xml_Lxml - Fatal编程技术网

使用pythonlxml处理嵌套元素

使用pythonlxml处理嵌套元素,python,xml,lxml,Python,Xml,Lxml,给出以下简单的XML数据: <book> <title>My First Book</title> <abstract> <para>First paragraph of the abstract</para> <para>Second paragraph of the abstract</para> </abstract>

给出以下简单的XML数据:

<book>
   <title>My First Book</title>
   <abstract>
         <para>First paragraph of the abstract</para>
         <para>Second paragraph of the abstract</para>
    </abstract>
    <keywordSet>
         <keyword>First keyword</keyword>
         <keyword>Second keyword</keyword>
         <keyword>Third keyword</keyword>
    </keywordSet>
</book>
我试图遵循,但上面的代码没有按预期工作

在另一种情况下,最好能够将整个XML树读入Python字典,每个元素作为键,每个文本作为元素项。我发现使用lxml objectify可以实现类似的功能,但我不知道如何实现它

在尝试用Python编写XML解析代码时,我发现一个真正的大问题是,提供的大多数“示例”都太简单,而且完全是虚构的,没有太多帮助——或者它们正好相反,使用了太复杂的自动生成的XML数据

谁能给我一个提示吗

提前谢谢

编辑:发布这个问题后,我找到了一个简单的解决方案

因此,我的更新代码变成:

from lxml import objectify
    root = objectify.fromstring(xml_string) # xml_string contains the XML data above
    print root.title # returns the book title
    for para in root.abstract.iterchildren():
        print para # now returns the text of all paragraphs
    for keyword in root.keywordSet.iterchildren():
        print keyword # now returns all keywords in the set

这非常简单,使用:

输出:

['First paragraph of the abstract', 'Second paragraph of the abstract']
['First keyword', 'Second keyword', 'Third keyword']
有关XPath语法的详细信息,请参阅

特别是,上述表达式中使用的元素使用

  • 使用
    /
    选择器选择根节点/直接子节点
  • text()
    操作符选择相应元素的文本节点(“文本内容”)

下面是如何使用Objectify API完成的:

from lxml import objectify

root = objectify.fromstring(xml_string)

paras = [p.text for p in root.abstract.para]
keywords = [k.text for k in root.keywordSet.keyword]

print paras
print keywords
似乎
root.abstract.para
实际上代表
root.abstract.para[0]
。因此,您需要显式使用
element.iterchildren()
来访问所有子元素

事实并非如此,我们显然都误解了Objectify API:
为了在
abstract
中迭代
para
,您需要迭代
root.abstract.para
,而不是
root.abstract
本身。这很奇怪,因为您直观地将
抽象
视为其节点的集合或容器,而该容器将由Python iterable表示。但实际上,代表序列的是
.para
选择器。

当然,好提示!但是,使用lxml objectfy是否也能达到同样的结果呢?毫无疑问,这是可能的。但特别是对于要遍历树的(深度)嵌套结构,XPath通常更容易阅读。虽然有objectify.ObjectPath,但提供的示例有点难看…:-(@user40893使用Objectify API更新了我的答案。请注意,尽管在您问题的解决方案中,
para
实际上不是一个字符串,但它是一个
StringElement
对象。如果您打印它,它看起来像一个字符串,但取决于您以后对它所做的操作,您可能需要访问实际的st使用
para.text
来响铃内容。事实上,下面的@LukasGraf answer也提供了同样的解决方案,但使用的方式更像python!:-)
['First paragraph of the abstract', 'Second paragraph of the abstract']
['First keyword', 'Second keyword', 'Third keyword']
from lxml import objectify

root = objectify.fromstring(xml_string)

paras = [p.text for p in root.abstract.para]
keywords = [k.text for k in root.keywordSet.keyword]

print paras
print keywords