从Python中的特定XML节点检索注释

时间:2019-11-20 16:55:03

标签: python xml

我有以下“ example.xml”文件

<?xml version="1.0" encoding="UTF-8"?>
<root>
  <tag1>
  <tag2>tag2<!-- comment = “this is the tag1 comment”--></tag2>
    <tag3>
        <tag4>tag4<!-- comment = “this is the tag4 comment”--></tag4>
    </tag3>
  </tag1>
</root>

我想检索对特定节点的评论。 目前,我只能使用以下命令从文件中检索所有注释

from lxml import etree

tree = etree.parse("example.xml")
comments = tree.xpath('//comment()')
print(comments)

如预期的那样,它将在列表中从文件中返回上述所有注释:

[<!-- comment = \u201cthis is the tag1 comment\u201d-->, <!-- comment = \u201cthis is the tag4 comment\u201d-->]

但是,我如何以及在哪里明确指定要检索其注释的节点?例如,如何指定tag2某处仅返回<!-- comment = \u201cthis is the tag4 comment\u201d-->

编辑

我有一个用例,我需要遍历XML文件的每个节点。如果迭代器到达具有多个子节点且带有注释的节点,则它将返回其子节点的所有注释。例如,考虑以下“ example2.xml”文件:

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <tag1>
    <tag2>
      <tag3>tag3<!-- comment = “this is the tag3 comment”--></tag3>
      <tag4>tag4<!-- comment = “this is the tag4 comment”--></tag4>
    </tag2>
  </tag1>
  <tag1>
    <tag2>
      <tag3>tag3<!-- comment = “this is the tag3 comment”--></tag3>
      <tag4>tag4<!-- comment = “this is the tag4 comment”--></tag4>
    </tag2>
  </tag1>
</root>

如果我执行与上述相同的步骤,则循环在tag1/tag2进行迭代时,它将返回tag3和tag4的所有注释。

即:

from lxml import etree

tree = etree.parse("example2.xml")
comments = tree.xpath('tag1[1]/tag2//comment()')
print(comments)

返回

[<!-- comment = \u201cthis is the tag3 comment\u201d-->, <!-- comment = \u201cthis is the tag4 comment\u201d-->]

因此,我的两个问题是:

  1. 如何只返回直接节点的注释,而不是包含其任何子节点?
  2. 结果以列表形式返回时,如何从所述列表中检索评论的值/文本?

3 个答案:

答案 0 :(得分:1)

您需要指定节点:

tree = etree.parse("example.xml")
comments = tree.xpath('//tag2/comment()')
print(comments)

输出:

[<!-- comment = “this is the tag1 comment”-->]

编辑:

对于您的嵌套结构,您需要遍历重复的标签:

tag2Elements = tree.xpath('//tag1/tag2')
for t2 in tag2Elements:
    t3Comment = t2.xpath('tag3/comment()')
    print(t2, t3Comment)

输出:

<Element tag2 at 0x1066b69b0> [<!-- comment = “this is the tag3 comment”-->]
<Element tag2 at 0x1066b6960> [<!-- comment = “this is the tag3 comment”-->]

答案 1 :(得分:1)

将xPath表达式更改为//tag2/comment()

仅指定//,即表示您允许任何标签的注释。

答案 2 :(得分:1)

您可以这样获得第一条评论:

>>> from lxml import etree
>>> with open('data.xml') as fd:
...  doc = etree.parse(fd)
...
>>> doc.xpath('/root/tag1/tag2/comment()')
[<!-- comment = “this is the tag1 comment”-->]

最后一条评论:

>>> doc.xpath('/root/tag1/tag3/tag4/comment()')
[<!-- comment = “this is the tag4 comment”-->]

......当然,如果这些元素是唯一的并且您不想使用完整路径,则可以使用//tag2//tag4