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

如何为包含<、>转义字符的XML编写XSLT?

处理嵌套转义XML的XSLT实现方案

这个问题我之前也碰到过——SOAP响应里的<executeReturn>节点内部是转义后的XML字符串(用&lt;代替<、&gt;代替>),XSLT默认会把它当成纯文本,没法直接遍历里面的<Message>、<Client>这些节点。核心解决思路是先把转义字符串还原成真实的XML节点树,再进行后续处理。下面给你两种可行的方案:

方案一:XSLT 2.0+ 原生解析(推荐)

现在大多数主流XSLT处理器(比如Saxon、Altova)都支持XSLT 2.0及以上版本,原生提供了parse-xml()函数可以直接解析XML字符串,不需要额外扩展。

示例实现

假设你的SOAP响应简化后是这样:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
  <soapenv:Header/>
  <soapenv:Body>
    <executeResponse>
      <executeReturn>
        &lt;Message&gt;
          &lt;Body&gt;
            &lt;Clients&gt;
              &lt;Client id="1"&gt;Alice&lt;/Client&gt;
              &lt;Client id="2"&gt;Bob&lt;/Client&gt;
            &lt;/Clients&gt;
          &lt;/Body&gt;
        &lt;/Message&gt;
      </executeReturn>
    </executeResponse>
  </soapenv:Body>
</soapenv:Envelope>

对应的XSLT代码:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">

  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="/">
    <!-- 1. 提取转义的XML字符串(合并所有文本节点,避免换行/空格拆分) -->
    <xsl:variable name="escaped-xml" select="string-join(/soapenv:Envelope/soapenv:Body/executeResponse/executeReturn/text(), '')"/>
    
    <!-- 2. 把转义字符串解析成XML节点树 -->
    <xsl:variable name="parsed-xml" select="parse-xml($escaped-xml)"/>

    <!-- 3. 像处理普通XML一样遍历解析后的节点 -->
    <xsl:apply-templates select="$parsed-xml/Message/Body/Clients/Client"/>
  </xsl:template>

  <!-- 自定义模板处理解析后的Client节点 -->
  <xsl:template match="Client">
    <Customer>
      <ID><xsl:value-of select="@id"/></ID>
      <Name><xsl:value-of select="."/></Name>
    </Customer>
  </xsl:template>

</xsl:stylesheet>

代码说明

  • string-join(..., ''):把<executeReturn>内分散的文本节点(比如换行、空格)拼接成完整的XML字符串,避免解析时因断行报错。
  • parse-xml():将转义字符串转换成可遍历的XML节点树,之后就能用常规XPath选择器定位内部节点。

方案二:XSLT 1.0 依赖处理器扩展函数

如果你的环境只能用XSLT 1.0,由于原生没有XML解析函数,需要依赖具体处理器的扩展功能。下面以常用的Xalan处理器为例:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
                xmlns:xalan="http://xml.apache.org/xalan"
                extension-element-prefixes="xalan">

  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="/">
    <xsl:variable name="escaped-xml" select="string-join(/soapenv:Envelope/soapenv:Body/executeResponse/executeReturn/text(), '')"/>
    <!-- 使用Xalan的扩展函数解析XML字符串 -->
    <xsl:variable name="parsed-xml" select="xalan:parseXML($escaped-xml)"/>

    <xsl:apply-templates select="$parsed-xml/Message/Body/Clients/Client"/>
  </xsl:template>

  <xsl:template match="Client">
    <Customer>
      <ID><xsl:value-of select="@id"/></ID>
      <Name><xsl:value-of select="."/></Name>
    </Customer>
  </xsl:template>

</xsl:stylesheet>

注意事项

  • 不同XSLT 1.0处理器的扩展函数不一样:比如MSXML需要用msxsl:script编写自定义解析逻辑,或者使用msxml:parse方法。你需要根据自己使用的处理器调整代码。

关键细节提醒

  • 确保转义的XML字符串是格式良好的:如果Web服务返回的内容有语法错误(比如未闭合的标签),解析函数会直接报错。
  • 如果<executeReturn>内有多余的空白字符,可以先用normalize-space()清理后再解析,但注意不要破坏XML结构。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:04:53