【问题标题】:Help With PHP and XPath帮助 PHP 和 XPath
【发布时间】:2011-06-02 01:59:05
【问题描述】:

我需要帮助在 PHP 中使用 XPath 做一些事情。

对于任何给定的 HTML,我需要:

  • 删除所有表格及其内容
  • 删除第一个 h1 标记之后的所有内容
  • 仅保留段落(包括其内部 HTML(链接、列表等))

使用正则表达式,我可以让一切正常运行。然而,当我遇到嵌套表时,我认为用正则表达式解析 HTML 确实很愚蠢。

非常感谢!

【问题讨论】:

  • 不使用 XSLT 处理 (x)Html 简直是愚蠢的。请提供您的 (x)Html 的完整示例(但尽可能精简)以及想要的结果。
  • 好问题,+1。有关完整而简短的 XSLT 解决方案,请参阅我的答案。 :)

标签: php regex xslt xpath html-parsing


【解决方案1】:

考虑使用 HTML DOM 解析器,因为这比 XML 更容易。有一些解析器也支持 xpath 语句。但棘手的部分是并非所有 HTML 都符合严格的 xhtml 标准,因此这些规则并不总是易于应用。这是我遇到的几个 DOM 解析器。有些支持 xpath,有些只是有其他选择内容的方式:

http://simplehtmldom.sourceforge.net/

http://php.net/manual/en/simplexmlelement.xpath.php

【讨论】:

【解决方案2】:

对于任何给定的 HTML,我需要:

• 删除所有表格及其内容

• 删除第一个 h1 之后的所有内容 标记

• 只保留段落(包括 它们的内部 HTML(链接、列表等))

这可以通过 XSLT 轻松完成

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

 <!-- Copy every node except when overriden
      by another template -->
 <xsl:template match="node()|@*">
  <xsl:copy>
   <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
 </xsl:template>

 <!-- Remove all tables and their contents -->
 <xsl:template match="h:table"/>

 <!-- Remove everything after the first h1 -->
 <xsl:template match="node()[preceding::h:h1]"/>

 <!-- Keep only paragraphs (INCLUDING
      their inner HTML (links, lists, etc))
  -->
 <xsl:template match=
 "node()[not(self::h:p) and not(ancestor::h:p)]">
  <xsl:apply-templates/>
 </xsl:template>
</xsl:stylesheet>

如果您的元素名称不在 XHtml 命名空间中,只需删除上述代码中出现的 h:

【讨论】:

  • 这很好。我将不得不阅读 XSLT。如何将这些解决方案与 PHP 结合起来?是否类似于使用 XPath 查询?
  • @Peter:我没有使用 PHP,但 AFAIK PHP 使用的是 LibXml/LibXslt 处理器。随便在网上搜一下就知道了——应该有很多例子。
猜你喜欢
  • 2020-08-30
  • 2011-02-12
  • 1970-01-01
  • 1970-01-01
  • 2011-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多