如何在XSL中处理输出转义XML元素并转换其TC节点?
解决方案:解析转义XML并转换TC节点
要处理嵌套在XML中的转义XML内容,核心是先将转义的字符串解析为可访问的XML节点集,之后就能用XPath操作其中的TC节点。以下是可行的XSLT 1.0实现方案:
正确的XSLT代码
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:exsl="http://exslt.org/common" exclude-result-prefixes="exsl"> <!-- 主入口模板 --> <xsl:template match="/"> <!-- 提取<TABEL_HUIDIGE_SITUATIE>内的转义XML字符串 --> <xsl:variable name="escaped-xml" select="/TABEL_HUIDIGE_SITUATIE/text()"/> <!-- 关闭输出转义,将字符串还原为真实XML节点,存储为结果树片段(RTF) --> <xsl:variable name="parsed-xml"> <xsl:value-of select="$escaped-xml" disable-output-escaping="yes"/> </xsl:variable> <!-- 将RTF转换为可通过XPath访问的节点集 --> <xsl:variable name="node-set" select="exsl:node-set($parsed-xml)"/> <!-- 对节点集中的所有节点应用模板,包括自定义的TC转换逻辑 --> <xsl:apply-templates select="$node-set/*"/> </xsl:template> <!-- 自定义TC节点转换模板(示例:添加自定义属性并保留原有内容) --> <xsl:template match="TC"> <xsl:copy> <!-- 复制原有属性 --> <xsl:copy-of select="@*"/> <!-- 添加自定义属性(仅当不存在时) --> <xsl:if test="not(@processed)"> <xsl:attribute name="processed">true</xsl:attribute> </xsl:if> <!-- 保留节点文本内容 --> <xsl:value-of select="."/> </xsl:copy> </xsl:template> <!-- 默认复制模板:保留原XML结构(除TC外的节点原样复制) --> <xsl:template match="*|@*|text()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> </xsl:stylesheet>
代码说明
- 提取转义字符串:通过
/TABEL_HUIDIGE_SITUATIE/text()精准获取嵌套的转义XML内容。 - 还原XML节点:使用
disable-output-escaping="yes"将转义字符串转换为真实的XML节点,存储为结果树片段(RTF)。 - 转换为可访问节点集:借助EXSLT的
exsl:node-set()函数,将RTF转换为可通过XPath查询的节点集,此时就能直接定位到TC节点。 - 自定义TC节点转换:编写匹配
TC节点的模板,实现所需的转换逻辑(示例中添加了标记处理状态的属性),其他节点通过默认模板原样保留结构。
替代方案(处理器支持exsl:parse时)
如果你的XSLT处理器支持EXSLT的exsl:parse扩展函数,可以更直接地解析转义字符串:
<xsl:variable name="node-set" select="exsl:parse($escaped-xml)"/>
这种方式无需先构建RTF,直接将字符串解析为节点集,代码更简洁。
注意事项
disable-output-escaping的支持依赖于XSLT处理器(如Xalan、Saxon均支持,部分轻量处理器可能不支持)。- 确保代码中正确引入EXSLT命名空间,避免前缀冲突。
内容的提问来源于stack exchange,提问作者Sai
相关产品推荐
相关产品推荐

