用于选择给定节点中所有文本的XPath表达式及其chldren的文本

时间:2012-05-03 02:01:08

标签: xpath

基本上我需要抓一些带有嵌套标签的文本。

这样的事情:

<div id='theNode'>
This is an <span style="color:red">example</span> <b>bolded</b> text
</div>

我想要一个会产生这个的表达式:

This is an example bolded text

我一直在努力工作一小时或更长时间没有结果。

感谢任何帮助

5 个答案:

答案 0 :(得分:21)

元素节点的string-value是文档顺序中元素节点的所有文本节点后代的字符串值的串联。

您想在div元素上调用XPath string()函数。

string(//div[@id='theNode'])

您还可以使用normalize-space函数来减少因源文档中的换行符和缩进而可能出现的不需要的空格。这将删除前导和尾随空格,并用单个空格替换空白字符序列。将节点集传递给normalize-space()时,首先将节点集转换为它的字符串值。如果没有参数传递给normalize-space,它将使用上下文节点。

normalize-space(//div[@id='theNode'])

// if theNode was the context node, you could use this instead
normalize-space()

您可能希望使用比我一直使用的示例XPath更有效的方法来选择上下文节点。例如,在某些浏览器中可以针对此页面运行以下Javascript示例。

var el = document.getElementById('question');
var result = document.evaluate('normalize-space()', el, null ).stringValue;

spanb元素之间的仅空白文本节点可能存在问题。

答案 1 :(得分:1)

使用

string(//div[@id='theNode'])

评估此表达式时,结果是文档中第一个(仅希望)div元素的字符串值。

由于元素的字符串值在 XPath Specification 中定义为所有文本节点后代的文档顺序中的串联,因此这正是所需的字符串。

因为这可能包含许多全白空间文本节点,您可能希望消除连续的前导和尾随空格,并用单个空格字符替换任何此类中间空格:

使用

normalize-space(string(//div[@id='theNode']))

基于XSLT的验证:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="/">
  "<xsl:copy-of select="string(//div[@id='theNode'])"/>"
===========
  "<xsl:copy-of select="normalize-space(string(//div[@id='theNode']))"/>"
 </xsl:template>
</xsl:stylesheet>

在提供的XML文档上应用此转换时:

<div id='theNode'> This is an 
    <span style="color:red">example</span>
    <b>bolded</b> text 
</div>

评估两个XPath表达式,并将这些评估的结果复制到输出

  " This is an 
    example
    bolded text 
"
===========
  "This is an example bolded text"

答案 2 :(得分:0)

这个怎么样:

/ div / text()[1] | / div / span / text()| / div / b / text()| / div / text()[2]

嗯,我不知道最后一部分。你可能不得不玩那个。

答案 3 :(得分:0)

如果您在python中使用scrapy,则可以使用descendant-or-self::*/text()。完整示例:

txt = """<div id='theNode'>
This is an <span style="color:red">example</span> <b>bolded</b> text
</div>"""

selector = scrapy.Selector(text=txt, type="html") # Create HTML doc from HTML text
all_txt = selector.xpath('//div/descendant-or-self::*/text()').getall()
final_txt = ''.join( _ for _ in all_txt).strip()
print(final_txt) # 'This is an example bolded text'

答案 4 :(得分:-1)

正常代码

// div [@ id ='theNode']

获取所有文本,但是如果它们被分割了,则

// div [@ id ='theNode'] / text()

不确定,但是如果您提供链接,我会尝试