1

我正在使用 XPath 从 HTML 页面中选择一个部分。但是,当我使用 XPath 提取节点时,它只正确选择了 HTML 标记周围的文本,而不是HTML 标记本身。

示例 HTML

<body>
    <div>
      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...
    </div>
</body>

我有以下 XPath

/body/div

我得到以下

At first glance you may ask, &#8220;what do you mean?&#8221; It means that we want to help figure...

我想

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...

如果您在示例 HTML 中注意到内容中有 a<i/><b />HTML 标记。当我提取内容时,这些标签中的单词会“丢失”。

如果这有所作为,我在 PHP 中使用 SimpleXML。

4

3 回答 3

3

您的 XPath 很好,但您可以删除 final /.,因为这是多余的:

/atom/content

所有的 HTML 都在一个<![CDATA ]]>部分中,因此在 XML DOM 中实际上只有文本。<i>and<b>标签不会被解析为标签,而只会显示为文本。使用 CDATA 部分与您的 XML 是这样编写的完全相同:

<atom>
    <content>
      At first glance you may ask, &amp;#8220;what &lt;i&gt;exactly&lt;/i&gt;
      do you mean?&amp;#8221; It means that we want to help &lt;b&gt;you&lt;/b&gt; figure...
    </content>
</atom>

因此,您<content>之后对元素所做的任何事情都会删除这些标签。您稍后是将文本解析为 HTML,还是通过过滤器运行它,或类似的东西?

于 2009-10-14T14:15:13.200 回答
1

SimpleXML 不喜欢文本节点,因此您必须改用自定义解决方案。

您可以asXML()在每个div元素上使用然后删除div标签,或者您可以将div元素转换为DOMNodes 然后循环$div->childNodes并序列化每个子元素。请注意,如果可用,您的 HTML 实体很可能会被实际字符替换。

或者,您可以查看SimpleDOM 项目并使用它的innerHTML()方法。

$html = 
'<body>
    <div>
      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...
    </div>
</body>';

$body = simpledom_load_string($html);

foreach ($body->xpath('/body/div') as $div)
{
    var_dump($div->innerHTML());
}
于 2009-11-12T16:06:09.513 回答
0

我不知道 SimpleXML 是否不同,但对我来说,您似乎需要确保选择所有节点类型而不仅仅是文本。在标准 XPath 中,你会做 /body/div/node()

于 2009-10-14T19:08:38.437 回答