使用XPath提取标签之间的文本和标记

10 投票
2 回答
14555 浏览
提问于 2025-04-18 08:19
  /span[@class="st"]/text()

我有以下这段XML:

...<span class="st">In Tim <em>Power</em>: Politieman...</span>...

我想提取标签之间的内容。为此,我使用XPath:

   /span[@class="st"]

不过,这样做会提取所有内容,包括标签本身。

这段代码会返回两个文本元素。一个是“In Tim”,另一个是“:Politieman”。而..部分不会被包含在内,它被当作分隔符处理。

有没有纯粹的XPath解决方案,可以返回:

In Tim <em>Power</em>: Politieman...

编辑
感谢@helderdarocha和@TextGeek。看来仅用XPath提取纯文本,包括部分并不简单。

使用/span[@class="st"]/node()的解决方案会创建一个包含各个行的列表,然后在Python中很容易将其转换为字符串。

2 个回答

3

听起来你想要一个类似于Javascript中innerHTML()函数的功能,但这是针对XML的。我觉得在纯XPath中没有办法做到这一点。

XPath其实并不直接处理像"<em>"和"</em>"这样的标记字符串,它是通过一棵节点对象的树来工作的(可能有某些XPath的实现尝试直接处理标记,但我对此表示怀疑)。大多数XPath的实现中根本不会有这四个字符"<em>"(除了可能用于打印错误信息之类的情况),而且当然,DOM可能是从头开始构建的,而不是从XML或其他输入生成的。同样,XPath也并不打算返回带有标记的字符串,而是返回节点的列表。

在XSLT或XQuery中,你可以很容易地做到这一点,但单靠XPath是做不到的,除非我遗漏了什么。

-s

10

要获取任何子节点,你可以使用:

/span[@class="st"]/node()

这段代码会返回:

  1. 两个子文本节点
  2. 完整的<em>节点(包括元素和内容)。

如果你想要获取所有的text()节点,包括在em里面的那些文本节点,那么可以获取所有的text()后代节点:

/span[@class="st"]//text()

或者

/span[@class="st"]/descendant::text()

这样会返回三个文本节点,包括<em>里面的文本,但不会返回<em>元素本身。

撰写回答