【问题标题】:Pulling out a full node with child nodes using XPath使用 XPath 拉出带有子节点的完整节点
【发布时间】:2009-10-14 14:04:20
【问题描述】:

我正在使用 XPath 从 HTML 页面中选择一个部分。但是,当我使用 XPath 提取节点时,它正确 只选择了 围绕 HTML 标签的文本,而 not 选择了 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, &amp;#8220;what do you mean?&amp;#8221; It means that we want to help figure...

我想要

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

如果您注意到示例 HTML 中的内容中有一个 &lt;i/&gt;&lt;b /&gt; HTML 标签。当我提取内容时,这些标签中的单词“丢失”了。

如果有区别的话,我在 PHP 中使用 SimpleXML。

【问题讨论】:

  • 我无法重现您的结果。使用 echo $result (即将 simplexmlelement 转换为字符串)和使用 ->asXML() 我在输出中得到“内部”标签。能否提供实际的测试代码?
  • 好的,所以我正在转换为 HTML,然后将其加载到 SimpleXML... 编辑问题以反映这一点。

标签: php xml xpath simplexml


【解决方案1】:

您的 XPath 很好,但您可以删除最后的 /.,因为那是多余的:

/atom/content

所有的 HTML 都在 &lt;![CDATA ]]&gt; 部分中,因此在 XML DOM 中实际上只有文本。 &lt;i&gt;&lt;b&gt; 标签不会被解析为标签,而只会显示为文本。使用 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>

所以,无论你对&lt;content&gt; 元素做什么,都会删除这些标签。您稍后是将文本解析为 HTML,还是通过过滤器运行它,或类似的东西?

【讨论】:

  • 删除了尾随句点...但是问题有所改变。
  • 我不认为 XPath 是问题,所以你能发布你的 PHP 代码吗?
【解决方案2】:

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

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

或者,您可以查看SimpleDOM project 并使用其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());
}

【讨论】:

    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 2014-07-25
      • 2012-06-24
      • 2017-02-24
      • 2021-06-09
      • 1970-01-01
      • 1970-01-01
      • 2011-01-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多