XSLT排序XML时仅复制标签值而非完整标签的问题求助
解决XSLT排序后丢失XML标签结构的问题
我来帮你搞定这个问题!你遇到的核心问题是缺少XSLT的标识转换模板(Identity Transform)——这个模板是XSLT处理中最基础的"兜底"模板,负责原样复制所有没有被自定义模板匹配到的节点、属性和文本内容。没有它的话,XSLT只会输出你明确指定处理的节点文本,而不会保留完整的XML标签结构。
问题分析
你当前的XSLT只定义了ContractSummary节点的处理模板,但当你对Offerings节点执行<xsl:apply-templates>时,没有对应的模板来复制整个Offerings节点及其子节点的完整结构,所以最终只输出了所有节点的文本内容,导致XML结构完全丢失。
另外还要注意:你的NonRecurringCharges标签可能缺失,直接用<xsl:sort select="NonRecurringCharges" />会导致缺失该标签的节点排序逻辑异常,我们需要给排序指定默认值来处理这种情况。
修正后的XSLT代码
<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> <!-- 自定义ContractSummary节点处理模板,负责排序Offerings --> <xsl:template match="ContractSummary"> <xsl:copy> <!-- 先复制除了Offerings之外的所有节点 --> <xsl:apply-templates select="@* | *[not(self::Offerings)]"/> <!-- 对Offerings节点进行排序后再处理 --> <xsl:apply-templates select="Offerings"> <!-- 按Type升序排序 --> <xsl:sort select="Type" order="ascending" data-type="text"/> <!-- 按NonRecurringCharges排序,缺失时用空字符串作为默认值 --> <xsl:sort select="NonRecurringCharges" order="ascending" data-type="text" default=""/> </xsl:apply-templates> </xsl:copy> </xsl:template> </xsl:stylesheet>
代码说明
- 标识转换模板:这是关键!它会递归复制所有节点(包括元素、属性、文本、注释等),确保除了我们自定义处理的
ContractSummary节点外,其他所有节点都保持原样。 - ContractSummary模板:
- 先复制
ContractSummary下除Offerings外的所有内容(比如你的OrderInfo节点) - 对
Offerings节点先按Type排序,再按NonRecurringCharges排序,同时给NonRecurringCharges的排序指定default="",避免缺失该标签的节点排序出错。
- 先复制
- 当
apply-templates处理Offerings节点时,会自动调用标识转换模板,完整复制每个Offerings节点及其所有子节点的结构。
输出结果
使用这个XSLT处理你的原始XML后,会得到你期望的完整XML结构,并且Offerings节点按Type排序,同类型的节点按NonRecurringCharges排序(缺失该标签的节点会排在同类型的前面,因为默认值是空字符串)。
内容的提问来源于stack exchange,提问作者Idur Jul
相关产品推荐
相关产品推荐

