基本上我需要抓一些带有嵌套标签的文本。
这样的事情:
<div id='theNode'>
This is an <span style="color:red">example</span> <b>bolded</b> text
</div>
我想要一个会产生这个的表达式:
This is an example bolded text
我一直在努力工作一小时或更长时间没有结果。
感谢任何帮助
答案 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;
span
和b
元素之间的仅空白文本节点可能存在问题。
答案 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()
不确定,但是如果您提供链接,我会尝试