【问题标题】:Can I parse an HTML using XSLT?我可以使用 XSLT 解析 HTML 吗?
【发布时间】:2009-10-28 19:44:55
【问题描述】:

我必须解析一个大的 HTML 文件,而我只对一小部分(表格)感兴趣。 因此,我考虑使用 XSLT 以更简单的方式简化/转换 HTML,然后我可以轻松处理。

我遇到的问题是找不到我的桌子。所以我不知道是否可以使用 XSL 样式表解析 HTML。

顺便说一下,HTML 文件是这样的(示意图,缺少标签):

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html id="ctl00_htmlDocumento" xmlns="http://www.w3.org/1999/xhtml" lang="es-ES" xml:lang="es-ES">
<div> some content </div>
<div class="NON_IMPORTANT"></div>
<div class="IMPORTANT_FATHER>
    <div class="IMPORTANT">
        <table>
            HERE IS THE DATA IM LOOKING FOR
        </table>
    </div>
</div>

根据要求,这是我的 xsl

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:template match="tbody">
        tbody found, lets process it
    <xsl:for-each select="tr">
        new tf found, lets process it
    </xsl:for-each>
    </xsl:template>

</xsl:stylesheet>

完整的 HTML 很大,所以我不知道如何在这里展示它...我已经在 Oxygen 上测试了有效文档,它说它是有效的。

提前致谢。 贡索

【问题讨论】:

  • XSLT 用于对输入文档执行转换而不是解析。此外,如果不显示您的 HTML 和 XSLT 文档,您将无法获得有用的答案。
  • 您可能想展示您是如何尝试使用样式表以及失败的样式表的 sn-p。
  • 你可以这样做,但我认为你会遇到麻烦。您应该在您的语言中使用支持草率 html 的 html 解析器。
  • 由于您的文档是 XHTML,XSLT 应该可以处理它,因此您的样式表可能有问题。如果没有看到试图处理表格的实际样式表,可能还有导致表格的 HTML 结构,就不可能再说更多了。

标签: html xslt parsing


【解决方案1】:

您没有在match 属性中正确使用XPath。您需要 xsl:stylesheet 元素中的 xmlns:xhtml="http://www.w3.org/1999/xhtml" 属性,然后您需要在 XPath 表达式中使用 xhtml: 前缀(您需要前缀;XPath 不遵循默认命名空间)。

在此之后,您仍然会遇到问题,即它也会处理其他所有内容。我不知道是否有更好的解决方案,但我认为您需要明确处理 tbody 元素路径上的内容,例如

<xsl:template match="xhtml:html">
  <xsl:apply-templates select="xhtml:body"/>
</xsl:template>

body 也是如此,以此类推,直到您到达 tbody 匹配项。

XPath 还支持比上述特定子更复杂的匹配。例如,匹配第三个孩子div 标签可以使用

<xsl:template match="xhtml:div[3]">

并将具有特定属性的元素与

匹配
<xsl:template match="xhtml:div[@class='IMPORTANT']">

这里的[] 包含了一个附加条件,该条件需要满足才能使元素被视为匹配项。纯数字表示对匹配项进行索引并仅采用具有该索引的匹配项(索引从 1 开始),@ 符号位于属性之前,但您可以在其中包含任意复杂的 XPath,因此您可以匹配几乎任何你想要的子结构。

【讨论】:

  • 谢谢,有帮助。有没有办法直接搜索内部标签?仅通过说明其名称或完整路径?
  • 您可以直接匹配它,但随后您将获得其他所有内容的默认行为,即打印其文本内容。如果您尝试使用&lt;xsl:template match="*"/&gt; 来消除默认行为,那也会影响您的根元素,因此它根本不会处理文档。因此,如果您只想处理文档中的单个元素,我认为您确实需要覆盖该元素路径上所有元素的默认行为。
  • 快到了。我已经添加了 HTML 架构。我的问题是:如何深入研究正确的“div”标签。有几个,但我只是对其中一些感兴趣。我可以按出现(即第三个 div 标签)或属性(即 class="IMPORTANT" 的 div 标签)过滤吗?再次感谢
  • @jk,更简单的方法是执行&lt;xsl:template match="*|text()"&gt;&lt;xsl:apply-templates/&gt;&lt;/xsl:template&gt; - 这会删除默认规则的所有输出,但确保处理整个树(因此其他规则可能仍然匹配)。
  • @Pavel,谢谢!这真的简化了我的 xsl。我可以问你它是如何/为什么起作用的吗?您如何阅读“*|text()”条件?任何标签或任何标签内的文本?如果是这种情况,为什么这条规则不优先于我创建的其他特定于标签的规则?像这样: 谢谢!
【解决方案2】:

只要您的 XHTML 文档格式正确,XML 解析器就可以读取它,因此 XSLT 引擎也可以对其进行转换。

假设,无法在文档中找到元素的最常见原因是:

  • 您的 XPath 表达式正在相对于您认为的不同节点执行。这对您的 XSLT 意味着什么 - 检查您的 XSLT 匹配模式相对于它们的模板是否正确。
  • 您尚未在 XPath 引擎中定义命名空间 URI 到前缀的映射。这对您的 XSLT 意味着什么 - 确保您在 XSLT 文件中声明了 xmlns="http://www.w3.org/1999/xhtml" 命名空间,带或不带前缀。

如果您发布您的 XSLT,我将能够进一步评论。

【讨论】:

    【解决方案3】:

    您可以使用 XSLT 来操作 HTML,前提是 HTML 格式正确(因为 HTML 文档是最严格意义上的格式正确的 XML 文档)。

    如果您可以确认这一点,并且您的 XSLT 无法正常工作,也许您应该提供 HTML 和 XSLT 文档的更全面的 sn-p,以便我们找出答案。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-02-01
      • 2011-06-17
      • 2016-06-21
      • 1970-01-01
      • 2011-01-27
      • 2012-09-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多