如何将3个独立运行的XSL转换合并为单个XSL文件?
合并三个XSL转换的方案
输入XML
<?xml version="1.0" encoding="UTF-8"?> <SHPMNT05> <IDOC BEGIN="1"> <EDI_DC40 SEGMENT="1"> <TABNAM>EDI_DC40</TABNAM> </EDI_DC40> <E1EDT20 SEGMENT="1"> <TKNUM>0000287203</TKNUM> <E1EDK33 SEGMENT="1"> <TSNUM>0001</TSNUM> <E1EDT44 SEGMENT="1"> <QUALI>001</QUALI> </E1EDT44> <E1EDT44 SEGMENT="1"> <QUALI>002</QUALI> <ABLAD>1</ABLAD> </E1EDT44> <E1EDT01 SEGMENT="1"> <VBELN>0081018666</VBELN> </E1EDT01> <E1EDT01 SEGMENT="1"> <VBELN>0081018667</VBELN> </E1EDT01> <E1EDT01 SEGMENT="1"> <VBELN>0081018668</VBELN> </E1EDT01> </E1EDK33> <E1EDK33 SEGMENT="1"> <TSNUM>0002</TSNUM> <E1EDT44 SEGMENT="1"> <QUALI>001</QUALI> </E1EDT44> <E1EDT44 SEGMENT="1"> <QUALI>002</QUALI> <ABLAD>2</ABLAD> </E1EDT44> <E1EDT01 SEGMENT="1"> <VBELN>0081018666</VBELN> </E1EDT01> <E1EDT01 SEGMENT="1"> <VBELN>0081018668</VBELN> </E1EDT01> </E1EDK33> <E1EDK33 SEGMENT="1"> <TSNUM>0002</TSNUM> <E1EDT44 SEGMENT="1"> <QUALI>001</QUALI> </E1EDT44> <E1EDT44 SEGMENT="1"> <QUALI>002</QUALI> <ABLAD>3</ABLAD> </E1EDT44> <E1EDT01 SEGMENT="1"> <VBELN>0081018666</VBELN> </E1EDT01> </E1EDK33> <E1EDL20 SEGMENT="1"> <VBELN>0081018666</VBELN> </E1EDL20> <E1EDL20 SEGMENT="1"> <VBELN>0081018667</VBELN> </E1EDL20> <E1EDL20 SEGMENT="1"> <VBELN>0081018668</VBELN> </E1EDL20> </E1EDT20> </IDOC> </SHPMNT05>
预期输出XML
<?xml version="1.0" encoding="UTF-8"?> <SHPMNT05> <IDOC BEGIN="1"> <EDI_DC40 SEGMENT="1"> <TABNAM>EDI_DC40</TABNAM> </EDI_DC40> <E1EDT20 SEGMENT="1"> <TKNUM>0000287203</TKNUM> <E1EDK33 SEGMENT="1"> <TSNUM>0001</TSNUM> <E1EDT44 SEGMENT="1"> <QUALI>001</QUALI> </E1EDT44> <E1EDT44 SEGMENT="1"> <QUALI>002</QUALI> <ABLAD>1</ABLAD> </E1EDT44> <E1EDT01 SEGMENT="1"> <VBELN>0081018667</VBELN> </E1EDT01> </E1EDK33> <E1EDK33 SEGMENT="1"> <TSNUM>0002</TSNUM> <E1EDT44 SEGMENT="1"> <QUALI>001</QUALI> </E1EDT44> <E1EDT44 SEGMENT="1"> <QUALI>002</QUALI> <ABLAD>2</ABLAD> </E1EDT44> <E1EDT01 SEGMENT="1"> <VBELN>0081018668</VBELN> </E1EDT01> </E1EDK33> <E1EDK33 SEGMENT="1"> <TSNUM>0002</TSNUM> <E1EDT44 SEGMENT="1"> <QUALI>001</QUALI> </E1EDT44> <E1EDT44 SEGMENT="1"> <QUALI>002</QUALI> <ABLAD>3</ABLAD> </E1EDT44> <E1EDT01 SEGMENT="1"> <VBELN>0081018666</VBELN> </E1EDT01> </E1EDK33> <E1EDL20 SEGMENT="1"> <VBELN>0081018667</VBELN> <ABLAD>1</ABLAD> </E1EDL20> <E1EDL20 SEGMENT="1"> <VBELN>0081018668</VBELN> <ABLAD>2</ABLAD> </E1EDL20> <E1EDL20 SEGMENT="1"> <VBELN>0081018666</VBELN> <ABLAD>3</ABLAD> </E1EDL20> </E1EDT20> </IDOC> </SHPMNT05>
原需求步骤
原需求通过三个独立XSL完成三项操作:
- 步骤1:过滤
E1EDK33中存在于后续同级节点的E1EDT01元素,仅保留每个VBELN在后续节点中不再出现的条目 - 步骤2:为
E1EDL20节点添加对应ABLAD元素,取值来自关联VBELN的E1EDK33节点 - 步骤3:根据新增的
ABLAD值对E1EDL20节点进行数字排序
合并后的XSL代码
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:strip-space elements="*"/> <xsl:output method="xml" indent="yes" encoding="UTF-8"/> <!-- 基础身份模板:复制未被特殊匹配的节点和属性 --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <!-- 实现步骤1:过滤重复的E1EDT01节点 --> <xsl:template match="/SHPMNT05/IDOC/E1EDT20/E1EDK33/E1EDT01[(VBELN = following-sibling::E1EDT01/VBELN) or (VBELN = ../following-sibling::E1EDK33/E1EDT01/VBELN)]"/> <!-- 实现步骤2:为E1EDL20添加ABLAD元素 --> <xsl:template match="/SHPMNT05/IDOC/E1EDT20/E1EDL20/VBELN"> <xsl:copy-of select="."/> <xsl:variable name="currentVbeln" select="."/> <ABLAD> <xsl:value-of select="/SHPMNT05/IDOC/E1EDT20/E1EDK33[E1EDT01/VBELN = $currentVbeln]/E1EDT44/ABLAD"/> </ABLAD> </xsl:template> <!-- 实现步骤3:对E1EDL20节点按ABLAD数字排序 --> <xsl:template match="E1EDT20"> <xsl:copy> <xsl:copy-of select="@*"/> <!-- 输出除E1EDL20外的所有子节点 --> <xsl:apply-templates select="*[not(self::E1EDL20)]"/> <!-- 排序并输出E1EDL20节点 --> <xsl:for-each select="E1EDL20"> <xsl:sort select="ABLAD" data-type="number"/> <xsl:apply-templates select="."/> </xsl:for-each> </xsl:copy> </xsl:template> <!-- 标准化文本内容,去除多余空格 --> <xsl:template match="text()"> <xsl:value-of select="normalize-space(.)"/> </xsl:template> </xsl:stylesheet>
代码说明
- 基础身份模板:保证XML结构的完整性,所有未被特殊模板匹配的节点和属性都会被原样复制。
- 重复节点过滤:通过匹配规则筛选出后续节点中会重复出现的
VBELN对应的E1EDT01节点,直接跳过输出。 - 添加ABLAD元素:针对
E1EDL20下的VBELN,查找关联E1EDK33中的ABLAD值并添加为新元素。 - 排序E1EDL20:重新处理
E1EDT20节点,先输出除E1EDL20外的所有内容,再按ABLAD数值排序输出E1EDL20节点。 - 文本标准化:统一处理所有文本内容,去除多余的空格和换行。
内容的提问来源于stack exchange,提问作者Mike Dole
相关产品推荐
相关产品推荐

