我正在使用XPath从HTML页面中选择一个部分。但是,当我使用XPath提取节点时,正确仅选择围绕 HTML标记,不 HTML标记本身。
示例HTML
<body>
<div>
At first glance you may ask, “what <i>exactly</i>
do you mean?” It means that we want to help <b>you</b> figure...
</div>
</body>
我有以下XPath
/body/div
我得到以下
At first glance you may ask, “what do you mean?” It means that we want to help figure...
我想要
At first glance you may ask, “what <i>exactly</i> do you mean?” It means that we want to help <b>you</b> figure...
如果您在示例HTML中注意到内容中有<i/>
和<b />
个HTML标记。当我提取内容时,这些标签中的单词会“丢失”。
如果有所不同,我在PHP中使用SimpleXML。
答案 0 :(得分:3)
您的XPath很好,但您可以删除最终的/.
,因为这是多余的:
/atom/content
所有HTML都在<![CDATA ]]>
部分内,因此在XML DOM中,您实际上只有文本。 <i>
和<b>
标记不会被解析为标记,而只会显示为文本。使用CDATA部分与XML的编写方式完全相同:
<atom>
<content>
At first glance you may ask, &#8220;what <i>exactly</i>
do you mean?&#8221; It means that we want to help <b>you</b> figure...
</content>
</atom>
因此,无论你在<content>
元素之后做什么,都会丢弃这些标签。您是稍后将文本解析为HTML,还是通过过滤器或类似的方式运行?
答案 1 :(得分:1)
SimpleXML不喜欢文本节点,因此您必须使用自定义解决方案。
您可以在每个asXML()
元素上使用div
,然后移除div
代码,也可以将div
元素转换为DOMNode
s然后循环$div->childNodes
并序列化每个孩子。请注意,如果可用,您的HTML实体很可能会替换为实际字符。
或者,您可以查看SimpleDOM project并使用其innerHTML()
方法。
$html =
'<body>
<div>
At first glance you may ask, “what <i>exactly</i>
do you mean?” It means that we want to help <b>you</b> figure...
</div>
</body>';
$body = simpledom_load_string($html);
foreach ($body->xpath('/body/div') as $div)
{
var_dump($div->innerHTML());
}
答案 2 :(得分:0)
我不知道SimpleXML是否不同,但对我而言,您似乎需要确保选择所有节点类型而不仅仅是文本。在标准XPath中,您可以执行/ body / div / node()