XSLT转换含可变子节点XML的无多层for-each实现方法
实现方案
完全不需要多层嵌套for-each,借助XSLT模板匹配机制和string-join函数即可完成需求,核心是穿透无业务意义的Loop容器节点,精准定位需要输出的报文段节点。
原有代码的缺陷
- 选择范围过窄:
select="/*"仅匹配最外层根节点,无法深入嵌套层级抓取内部的CLP、NM1节点 - 未过滤容器节点:将仅做层级嵌套的Loop20、Loop21也纳入输出逻辑,导致内容混乱
- 缺失重复节点处理:碰到多个同名NM1节点时,无法将其拆分为独立行输出
简化实现代码
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- 穿透所有Loop开头的容器节点,不做直接输出 --> <xsl:template match="*[starts-with(local-name(), 'Loop')]"> <xsl:apply-templates/> </xsl:template> <!-- 匹配CLP、NM1这类字段全为F开头的业务报文段节点 --> <xsl:template match="*[ not(starts-with(local-name(), 'Loop')) and count(./*) > 0 and not(*[not(starts-with(local-name(), 'F'))]) ]"> <!-- 拼接节点名与所有字段值,整行输出 --> <xsl:value-of select="concat(local-name(), string-join(./*, '*'), ' ')"/> <!-- 处理节点内嵌套的其他业务段 --> <xsl:apply-templates/> </xsl:template> <!-- 忽略零散文本,避免多余输出 --> <xsl:template match="text()"/> </xsl:stylesheet>
方案特点
- 无多层循环嵌套:无论Loop容器嵌套多少层,模板会自动遍历穿透,定位内部的业务段节点
- 自动适配重复同类节点:多个NM1节点会被分别匹配、独立输出为要求格式的行,无需额外写重复处理逻辑
- 字段拼接效率高:用
string-join(./*, '*')一句话完成所有字段值的*分隔拼接,替代冗余的内层循环
内容的提问来源于stack exchange,提问作者H22
相关产品推荐
相关产品推荐

