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

如何在XSLT 2.0中递归匹配另一模板内的模板并取值?

解决XSLT中提取值并插入/后的问题

嘿,我完全懂你这几天被这个问题卡得难受——想把里的内容抠出来,放到节点下的后面,结果自己写的xsl:function输出了整个节点而非仅需要的值,对吧?别着急,咱们来一步步搞定它。

首先得明确核心:你要的是的文本内容(或者内部子节点),不是整个标签本身。下面给你两种实用的解决方案,按需选就行:

方法一:用模板匹配(最直观的常规写法)

先假设你的源XML结构大概是这样(如果实际结构不同,调整XPath路径就行):

<library>
  <book>
    <author>George Orwell</author>
    <title>1984</title>
  </book>
  <feedback>A timeless classic about totalitarianism</feedback>
</library>

我们可以用XSLT的身份模板复制所有默认节点,然后专门针对<book>节点做自定义处理,在复制完所有子节点后插入的内容:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <!-- 身份模板:默认复制所有节点、属性 -->
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <!-- 自定义处理book节点 -->
  <xsl:template match="book">
    <xsl:copy>
      <!-- 先复制book下原有的所有子节点(比如author、title) -->
      <xsl:apply-templates select="node()"/>
      <!-- 插入新的feedback节点,只取原feedback的文本内容 -->
      <feedback>
        <xsl:value-of select="/library/feedback"/>
      </feedback>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

如果你的里不是纯文本,还有嵌套子节点(比如<feedback><text>...</text><rating>5</rating></feedback>),那就把xsl:value-of换成xsl:copy-of select="/library/feedback/node()",这样就能完整复制的内部内容。

方法二:修正你的xsl:function

如果坚持要用函数来实现,问题大概率出在你的函数返回了整个节点,而非它的内部内容。咱们来修正一下:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:my="http://example.com/myfunctions">
  <!-- 身份模板依旧保留 -->
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <!-- 自定义函数,返回feedback的文本内容 -->
  <xsl:function name="my:getFeedbackContent">
    <xsl:param name="currentNode"/>
    <!-- 注意XPath路径:从当前节点(比如author)找到父节点book,再找兄弟节点feedback -->
    <xsl:value-of select="$currentNode/../feedback"/>
    <!-- 若要保留子节点,换成:<xsl:copy-of select="$currentNode/../feedback/node()"/> -->
  </xsl:function>

  <!-- 处理author节点,在其后插入feedback内容 -->
  <xsl:template match="author">
    <xsl:copy-of select="."/> <!-- 先复制原author节点 -->
    <!-- 调用函数生成新的feedback节点 -->
    <feedback>
      <xsl:value-of select="my:getFeedbackContent(.)"/>
    </feedback>
  </xsl:template>
</xsl:stylesheet>

这里要注意XPath的路径正确性:如果和是兄弟节点,$currentNode/../feedback就能准确定位到它;如果结构更深,就调整路径层级。

关键提醒点

  • 用xsl:value-of获取纯文本内容,用xsl:copy-of获取节点的内部子结构
  • 务必确保XPath路径能精准定位到目标节点,别写错层级
  • 如果你用的是XSLT 1.0,函数需要放在命名空间下(XSLT 2.0+支持无命名空间函数,但还是建议加命名空间避免冲突)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 09:20:22