You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过XSL从XML的CDATA中提取<ul>/<li>元素并输出可样式化HTML?

解决CDATA中HTML列表的XSL转换问题

我懂你的困扰——用xsl:value-of输出CDATA里的列表时,它只会把整个内容当成纯文本输出,标签都变成转义后的字符串,根本没法直接添加类名做样式。下面分两种常用的XSLT版本给你靠谱的解决方案:

方案1:XSLT 2.0+ (推荐,更灵活可控)

XSLT 2.0及以上版本自带了parse-xml()函数,能直接把CDATA里的HTML字符串解析成可操作的XML节点集,这样你就能轻松遍历并修改列表元素的类名了。

完整的XSLT示例代码:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <!-- 保留你的键定义 -->
  <xsl:key name="fooditem" match="FoodItem" use="@ID" />

  <xsl:template match="/">
    <div class="food">
      <!-- 把CDATA内容解析成XML节点 -->
      <xsl:variable name="parsedList" select="parse-xml(key('fooditem', 1)/Content)" />
      <!-- 生成带类名的外层ul -->
      <ul class="fooditems">
        <!-- 遍历解析后的li节点,生成带类名的li -->
        <xsl:for-each select="$parsedList/ul/li">
          <li class="fooditem">
            <xsl:value-of select="." />
          </li>
        </xsl:for-each>
      </ul>
    </div>
  </xsl:template>
</xsl:stylesheet>

这个方法的优势很明显:不管CDATA里的列表结构有多复杂(比如li里嵌套了其他HTML标签),你都能精准操作节点,完全不会破坏原有内容的结构。

方案2:XSLT 1.0 (兼容旧环境)

如果只能用XSLT 1.0,因为没有内置的XML解析函数,我们可以通过字符串替换给原有的ul/li标签手动添加类名,再禁用输出转义让浏览器识别这些HTML标签。

完整的XSLT示例代码:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:key name="fooditem" match="FoodItem" use="@ID" />

  <xsl:template match="/">
    <div class="food">
      <!-- 获取原始CDATA内容 -->
      <xsl:variable name="rawContent" select="key('fooditem', 1)/Content" />
      <!-- 替换<ul>为带类名的<ul> -->
      <xsl:variable name="ulWithClass">
        <xsl:call-template name="replace-string">
          <xsl:with-param name="text" select="$rawContent" />
          <xsl:with-param name="replace" select="'&lt;ul&gt;'" />
          <xsl:with-param name="with" select="'&lt;ul class=&quot;fooditems&quot;&gt;'" />
        </xsl:call-template>
      </xsl:variable>
      <!-- 替换<li>为带类名的<li> -->
      <xsl:variable name="finalContent">
        <xsl:call-template name="replace-string">
          <xsl:with-param name="text" select="$ulWithClass" />
          <xsl:with-param name="replace" select="'&lt;li&gt;'" />
          <xsl:with-param name="with" select="'&lt;li class=&quot;fooditem&quot;&gt;'" />
        </xsl:call-template>
      </xsl:variable>
      <!-- 输出时禁用转义,让标签生效 -->
      <xsl:value-of select="$finalContent" disable-output-escaping="yes" />
    </div>
  </xsl:template>

  <!-- XSLT 1.0通用字符串替换模板 -->
  <xsl:template name="replace-string">
    <xsl:param name="text" />
    <xsl:param name="replace" />
    <xsl:param name="with" />
    <xsl:choose>
      <xsl:when test="contains($text, $replace)">
        <xsl:value-of select="substring-before($text, $replace)" />
        <xsl:value-of select="$with" />
        <xsl:call-template name="replace-string">
          <xsl:with-param name="text" select="substring-after($text, $replace)" />
          <xsl:with-param name="replace" select="$replace" />
          <xsl:with-param name="with" select="$with" />
        </xsl:call-template>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="$text" />
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
</xsl:stylesheet>

注意:这个方法依赖于CDATA里的列表标签格式固定(比如都是纯<ul>和<li>,没有额外属性),如果原标签有其他属性,需要调整替换的匹配字符串。


内容的提问来源于stack exchange,提问作者friiitzdesign

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 08:18:25