【问题标题】:Parsing HTML inside a CDATA block using an XSL file使用 XSL 文件解析 CDATA 块内的 HTML
【发布时间】:2019-01-31 23:37:12
【问题描述】:

我想为 <p> 标记解析 CDATA 块内的 HTML,并将每个标记输出到单独的表格行中。但是我不太明白,想知道是否有人可以帮助我?

我一直在尝试解析 HTML,但无法弄清楚如何解析它而不是简单地将其视为字符数据。我很确定我无法用 XSL 1.0 做到这一点,如果需要我可以使用 2.0。

XML

<XML_FILE>
  <NOTE>
    <TEXT TITLE="TEST">
      <![CDATA[<p>first p tag and <strong>bold</strong></p><p>second p tag and  <u>underline</u></p>]]>
    </TEXT>
  </NOTE>
</XML_FILE>

XSL

<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

  <xsl:template match="NOTE">
    <div class="tableWrapper">
      <table class="body">
        <xsl:apply-templates select="TEXT"/>
      </table>
    </div>
  </xsl:template>

  <xsl:template match="TEXT">
    <xsl:value-of select="." disable-output-escaping="yes"/>
  </xsl:template>

</xsl:stylesheet>

输出

<div class="tableWrapper">
   <table class="body"><p>first p tag and <strong>bold</strong></p><p>second p tag and <u>underline</u></p></table>
</div>

期望的输出

<div class="tableWrapper">
   <table class="body">
      <tr><td><p>first p tag and <strong>bold</strong></p></td></tr>
      <tr><td><p>second p tag and <u>underline</u></p></td></tr>
   </table>
</div>

提供所需输出的最终样式表

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="#all"
    version="3.0">

  <xsl:mode on-no-match="shallow-copy"/>

  <xsl:output method="html" indent="yes" html-version="5"/>
  <xsl:strip-space elements="*"/>

  <xsl:template match="XML_FILE">
      <xsl:apply-templates/>
  </xsl:template>

  <xsl:template match="NOTE">
    <div class="tableWrapper">
      <table class="body">
        <xsl:apply-templates select="parse-xml-fragment(TEXT)/node()"/>
      </table>
    </div>
  </xsl:template>

  <xsl:template match="p">
      <tr>
          <td>
              <xsl:next-match/>
          </td>
      </tr>
  </xsl:template>

</xsl:stylesheet>

【问题讨论】:

    标签: html xml xslt


    【解决方案1】:

    XSLT 3.0 有一个函数 parse-xml-fragment() 可以解决这个问题。

    在早期的 XSLT 版本中没有任何等价物,尽管您可能会找到可以帮助您的供应商扩展。大多数处理器允许您编写自己的外部函数,您可以从 XSLT 代码中调用这些函数,并且您可以编写这样的函数,将 CDATA 内容传递给外部 XML 解析器以转换为树结构。

    【讨论】:

    • parse-xml-fragment 可以获取

      标记的内容,但是如何遍历 &lt;p&gt; 节点?使用&lt;xsl:value-of select="parse-xml-fragment(.)" disable-output-escaping="yes"/&gt; 给出输出&lt;table class="body"&gt;first p tag and boldsecond p tag and underline&lt;/table&gt;

    • parse-xml-fragment(.) 返回document-node()。所以你应该首先在match="TEXT"模板中生成trtd,然后在td中添加&lt;xsl:copy-of select="parse-xml-fragment(.)"/&gt;就可以了。
    • 这更接近,但仍然不是我想要的。使用&lt;tr&gt;&lt;td&gt;&lt;xsl:copy-of select="parse-xml-fragment(.)"/&gt;&lt;/td&gt;&lt;/tr&gt; 给出输出&lt;tr&gt;&lt;td&gt;&lt;p&gt;first ...&lt;/p&gt;&lt;p&gt;second ...&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;。我希望的输出是&lt;tr&gt;&lt;td&gt;&lt;p&gt;first...&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;second...&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;。也许我理解错了?
    • 当然,如果您想映射/转换 parse-xml-fragment 返回的节点(例如,将 p 元素包装到 trtd 中),您可以这样做使用更多模板,请参阅xsltfiddle.liberty-development.net/ej9EGbT/1,就像您对需要转换的任何节点所做的那样,无论它们是在主 XML 文档中还是由 doc 函数解析,或者在您的情况下由 parse-xml-fragment 解析,跨度>
    猜你喜欢
    • 2018-02-10
    • 2013-03-28
    • 1970-01-01
    • 2015-07-02
    • 1970-01-01
    • 1970-01-01
    • 2013-02-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多