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

能否对Map与Array结构使用apply-templates进行匹配转换?

XSLT中Map/Array无法直接使用apply-templates的解决方案

apply-templates是XSLT专为XML节点设计的核心指令,默认确实不直接支持Map、Array这类XPath 3.0+引入的序列类型,你遇到的情况是正常的设计限制,以下是几种可行的适配方案:

1. 将Map/Array转换为临时XML节点集

把非节点结构转成XML节点序列,就能复用apply-templates的节点匹配逻辑:

<xsl:template match="/">
  <!-- 示例数组变量 -->
  <xsl:variable name="demo-array" select="('apple', 'banana', 'cherry')"/>
  <!-- 转换为XML节点 -->
  <xsl:variable name="array-nodes">
    <xsl:for-each select="$demo-array">
      <fruit><xsl:value-of select="."/></fruit>
    </xsl:for-each>
  </xsl:variable>
  <!-- 正常使用apply-templates -->
  <xsl:apply-templates select="$array-nodes/fruit"/>
</xsl:template>

<xsl:template match="fruit">
  <processed-fruit><xsl:value-of select="concat('Processed: ', upper-case(.))"/></processed-fruit>
</xsl:template>

处理Map时,可遍历键值对生成节点:

<xsl:variable name="demo-map" select="map { 'id': '1001', 'name': 'Alice' }"/>
<xsl:variable name="map-nodes">
  <xsl:for-each select="map:keys($demo-map)">
    <entry key="{.}"><xsl:value-of select="$demo-map(.)"/></entry>
  </xsl:for-each>
</xsl:variable>
<xsl:apply-templates select="$map-nodes/entry"/>

2. 用for-each结合模板调用替代

如果不想转换为XML节点,可直接遍历Map/Array,通过call-template传递元素进行处理:

<xsl:template match="/">
  <xsl:variable name="demo-map" select="map { 'price': '29.99', 'stock': '50' }"/>
  <xsl:for-each select="$demo-map?*">
    <xsl:call-template name="process-map-entry">
      <xsl:with-param name="entry-value" select="."/>
    </xsl:call-template>
  </xsl:for-each>
</xsl:template>

<xsl:template name="process-map-entry">
  <xsl:param name="entry-value"/>
  <formatted-entry><xsl:value-of select="concat('Formatted: ', format-number($entry-value, '#,##0.00'))"/></formatted-entry>
</xsl:template>

3. 利用XSLT 3.0模式扩展(需支持的处理器如Saxon)

部分XSLT 3.0处理器允许扩展模式来匹配原子值,可直接对Array元素应用模板:

<!-- 定义自定义模式 -->
<xsl:mode name="process-array" on-no-match="shallow-copy"/>

<!-- 匹配字符串类型的数组元素 -->
<xsl:template match="xs:string" mode="process-array">
  <array-item><xsl:value-of select="concat('Uppercase: ', upper-case(.))"/></array-item>
</xsl:template>

<xsl:template match="/">
  <xsl:variable name="demo-array" select="('red', 'green', 'blue')"/>
  <!-- 对数组元素应用指定模式的模板 -->
  <xsl:apply-templates select="$demo-array" mode="process-array"/>
</xsl:template>

内容的提问来源于stack exchange,提问作者MrD at KookerellaLtd

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 18:43:14