带有动态过滤器的 XSLT for-each 循环
XSLT for-each loops with dynamic filters
这是 XML-Message (SAP-IDOC) 的简化版本,我需要将其转换为更易于阅读的 XML,如下例所示。
这是一个 SAP Delivery IDOC,它为我提供了货物及其位置的信息。问题是,位置 10 和 20 可能在同一个纸箱 (E1EDL37) 中,并且具有与位置 3 不同的跟踪编号 (Field TRACKN)。
<DELVRY07>
<IDOC>
<E1EDL20> <!-- Contains all positions-->
<E1EDL24> <!--one Node for each position -->
<POSNR>000010</POSNR>
<MATNR>123</MATNR>
<E1EDL41>
<BSTNR>Fall 1</BSTNR>
</E1EDL41>
</E1EDL24>
<E1EDL24><!--one Node for each position -->
<POSNR>000020</POSNR>
<MATNR>456</MATNR>
<E1EDL41>
<BSTNR>Fall 2</BSTNR>
</E1EDL41>
</E1EDL24>
<E1EDL24><!--one Node for each position -->
<POSNR>000030</POSNR>
<MATNR>789</MATNR>
<E1EDL41>
<BSTNR>Fall 3</BSTNR>
</E1EDL41>
</E1EDL24>
<E1EDL37><!--one Node for every carton-->
<E1EDL49>
<XSITD>UPS1</XSITD>
<TRACKN>Track 1</TRACKN>
</E1EDL49>
<E1EDL44><!-- every position in the carton-->
<VBELN>123456</VBELN>
<POSNR>000010</POSNR>
</E1EDL44>
<E1EDL44><!-- every position in the carton-->
<VBELN>456789</VBELN>
<POSNR>000020</POSNR>
</E1EDL44>
</E1EDL37>
<E1EDL37><!--one Node for every carton-->
<E1EDL49>
<XSITD>DPD</XSITD>
<TRACKN>Track 2</TRACKN>
</E1EDL49>
<E1EDL44><!-- every position in the carton-->
<VBELN>123456</VBELN>
<POSNR>000030</POSNR>
</E1EDL44>
</E1EDL37>
</E1EDL20>
</IDOC>
</DELVRY07>
这应该是xslt转换后的xml消息(或类似的消息):
<Shipment>
<Positions>
<POSNR>000010</POSNR>
<MATNR>123</MATNR>
<BSTNR>Fall 1</BSTNR>
<TRACKN>Track 1</TRACKN>
<XSITD>UPS1</XSITD>
</Positions>
<Positions>
<POSNR>000020</POSNR>
<MATNR>456</MATNR>
<BSTNR>Fall 2</BSTNR>
<TRACKN>Track 1</TRACKN>
<XSITD>UPS1</XSITD>
</Positions>
<Positions>
<POSNR>000030</POSNR>
<MATNR>123</MATNR>
<BSTNR>Fall 3</BSTNR>
<TRACKN>Track 2</TRACKN>
<XSITD>DPD</XSITD>
</Positions>
</Shipment>
我试着用循环遍历 E1EDL24 元素并将信息写入变量。但从那时起,我将需要对所有 E1EDL44 进行循环并获取上面 E1EDL49 元素的 TRACKN 字段的值。
你能帮我想办法吗?
非常感谢您的帮助!
如果我正确地遵循了这一点(这完全不确定),您想为每个 "position" 创建一个记录并从匹配的 "carton":
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="carton-by-position" match="E1EDL37" use="E1EDL44/POSNR" />
<xsl:template match="/DELVRY07">
<Shipment>
<xsl:for-each select="IDOC/E1EDL20/E1EDL24">
<Positions>
<xsl:copy-of select="POSNR | MATNR | E1EDL41/BSTNR"/>
<xsl:copy-of select="key('carton-by-position', POSNR)/E1EDL49/*"/>
</Positions>
</xsl:for-each>
</Shipment>
</xsl:template>
</xsl:stylesheet>
试试这个模板:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/IDOC/E1EDL20">
<xsl:variable name="parent" select="."/>
<Shipment>
<xsl:for-each select="E1EDL24/POSNR">
<xsl:variable name="posnr" select="."/>
<Position>
<POSNR><xsl:value-of select="$posnr"/></POSNR>
<MATNR><xsl:value-of select="../MATNR"/></MATNR>
<BSTNR><xsl:value-of select="../E1EDL41/BSTNR"/></BSTNR>
<TRACKN><xsl:value-of select="$parent/E1EDL37[E1EDL44/POSNR=$posnr]/E1EDL49/TRACKN"/></TRACKN>
<XSITD><xsl:value-of select="$parent/E1EDL37[E1EDL44/POSNR=$posnr]/E1EDL49/XSITD"/></XSITD>
</Position>
</xsl:for-each>
</Shipment>
</xsl:template>
</xsl:stylesheet>
这是 XML-Message (SAP-IDOC) 的简化版本,我需要将其转换为更易于阅读的 XML,如下例所示。
这是一个 SAP Delivery IDOC,它为我提供了货物及其位置的信息。问题是,位置 10 和 20 可能在同一个纸箱 (E1EDL37) 中,并且具有与位置 3 不同的跟踪编号 (Field TRACKN)。
<DELVRY07>
<IDOC>
<E1EDL20> <!-- Contains all positions-->
<E1EDL24> <!--one Node for each position -->
<POSNR>000010</POSNR>
<MATNR>123</MATNR>
<E1EDL41>
<BSTNR>Fall 1</BSTNR>
</E1EDL41>
</E1EDL24>
<E1EDL24><!--one Node for each position -->
<POSNR>000020</POSNR>
<MATNR>456</MATNR>
<E1EDL41>
<BSTNR>Fall 2</BSTNR>
</E1EDL41>
</E1EDL24>
<E1EDL24><!--one Node for each position -->
<POSNR>000030</POSNR>
<MATNR>789</MATNR>
<E1EDL41>
<BSTNR>Fall 3</BSTNR>
</E1EDL41>
</E1EDL24>
<E1EDL37><!--one Node for every carton-->
<E1EDL49>
<XSITD>UPS1</XSITD>
<TRACKN>Track 1</TRACKN>
</E1EDL49>
<E1EDL44><!-- every position in the carton-->
<VBELN>123456</VBELN>
<POSNR>000010</POSNR>
</E1EDL44>
<E1EDL44><!-- every position in the carton-->
<VBELN>456789</VBELN>
<POSNR>000020</POSNR>
</E1EDL44>
</E1EDL37>
<E1EDL37><!--one Node for every carton-->
<E1EDL49>
<XSITD>DPD</XSITD>
<TRACKN>Track 2</TRACKN>
</E1EDL49>
<E1EDL44><!-- every position in the carton-->
<VBELN>123456</VBELN>
<POSNR>000030</POSNR>
</E1EDL44>
</E1EDL37>
</E1EDL20>
</IDOC>
</DELVRY07>
这应该是xslt转换后的xml消息(或类似的消息):
<Shipment>
<Positions>
<POSNR>000010</POSNR>
<MATNR>123</MATNR>
<BSTNR>Fall 1</BSTNR>
<TRACKN>Track 1</TRACKN>
<XSITD>UPS1</XSITD>
</Positions>
<Positions>
<POSNR>000020</POSNR>
<MATNR>456</MATNR>
<BSTNR>Fall 2</BSTNR>
<TRACKN>Track 1</TRACKN>
<XSITD>UPS1</XSITD>
</Positions>
<Positions>
<POSNR>000030</POSNR>
<MATNR>123</MATNR>
<BSTNR>Fall 3</BSTNR>
<TRACKN>Track 2</TRACKN>
<XSITD>DPD</XSITD>
</Positions>
</Shipment>
我试着用循环遍历 E1EDL24 元素并将信息写入变量。但从那时起,我将需要对所有 E1EDL44 进行循环并获取上面 E1EDL49 元素的 TRACKN 字段的值。
你能帮我想办法吗?
非常感谢您的帮助!
如果我正确地遵循了这一点(这完全不确定),您想为每个 "position" 创建一个记录并从匹配的 "carton":
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="carton-by-position" match="E1EDL37" use="E1EDL44/POSNR" />
<xsl:template match="/DELVRY07">
<Shipment>
<xsl:for-each select="IDOC/E1EDL20/E1EDL24">
<Positions>
<xsl:copy-of select="POSNR | MATNR | E1EDL41/BSTNR"/>
<xsl:copy-of select="key('carton-by-position', POSNR)/E1EDL49/*"/>
</Positions>
</xsl:for-each>
</Shipment>
</xsl:template>
</xsl:stylesheet>
试试这个模板:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/IDOC/E1EDL20">
<xsl:variable name="parent" select="."/>
<Shipment>
<xsl:for-each select="E1EDL24/POSNR">
<xsl:variable name="posnr" select="."/>
<Position>
<POSNR><xsl:value-of select="$posnr"/></POSNR>
<MATNR><xsl:value-of select="../MATNR"/></MATNR>
<BSTNR><xsl:value-of select="../E1EDL41/BSTNR"/></BSTNR>
<TRACKN><xsl:value-of select="$parent/E1EDL37[E1EDL44/POSNR=$posnr]/E1EDL49/TRACKN"/></TRACKN>
<XSITD><xsl:value-of select="$parent/E1EDL37[E1EDL44/POSNR=$posnr]/E1EDL49/XSITD"/></XSITD>
</Position>
</xsl:for-each>
</Shipment>
</xsl:template>
</xsl:stylesheet>