如何使用XSLT(内部循环问题)转换此XML?

如何使用XSLT(内部循环问题)转换此XML?,xml,xslt,Xml,Xslt,我有一个特定的XML输出结构,它不符合我的要求。出于这个原因,我正在研究使用XSLT代码将当前结构转换为所需结构的可能性 我知道我需要使用XSLT变量和if条件来完成所需的输出 这是我当前的XML输入: <ShipmentInstruction> <CarrierCode>AFH</CarrierCode> <CarrierProductCode>AFH</CarrierProductCode>

我有一个特定的XML输出结构,它不符合我的要求。出于这个原因,我正在研究使用XSLT代码将当前结构转换为所需结构的可能性

我知道我需要使用XSLT变量和if条件来完成所需的输出

这是我当前的XML输入:

<ShipmentInstruction>
        <CarrierCode>AFH</CarrierCode>
        <CarrierProductCode>AFH</CarrierProductCode>
        <ShipmentNoOfBoxes>2</ShipmentNoOfBoxes>
        <Boxes>
          <Box>
            <ShipmentBoxNr>0000000011</ShipmentBoxNr>
            <ShipmentBoxReference>0000000011</ShipmentBoxReference>
            <ShipmentBoxWeight>1.5</ShipmentBoxWeight>
            <Contents>
              <Content>
                <BarCode>8719829088824</BarCode>
              </Content>
            </Contents>
          </Box>
          <Box>
            <ShipmentBoxNr>0000000011</ShipmentBoxNr>
            <ShipmentBoxReference>0000000011</ShipmentBoxReference>
            <ShipmentBoxWeight>1.5</ShipmentBoxWeight>
            <Contents>
              <Content>
                <BarCode>8719829088831</BarCode>
              </Content>
            </Contents>
          </Box>
          <Box>
            <ShipmentBoxNr>0000000011</ShipmentBoxNr>
            <ShipmentBoxReference>0000000011</ShipmentBoxReference>
            <ShipmentBoxWeight>1.5</ShipmentBoxWeight>
            <Contents>
              <Content>
                <BarCode>8719829088848</BarCode>
              </Content>
            </Contents>
          </Box>
          <Box>
            <ShipmentBoxNr>0000000022</ShipmentBoxNr>
            <ShipmentBoxReference>0000000022</ShipmentBoxReference>
            <ShipmentBoxWeight>7.5</ShipmentBoxWeight>
            <Contents>
              <Content>
                <BarCode>8719829088572</BarCode>
              </Content>
            </Contents>
          </Box>
          <Box>
            <ShipmentBoxNr>0000000022</ShipmentBoxNr>
            <ShipmentBoxReference>0000000022</ShipmentBoxReference>
            <ShipmentBoxWeight>7.5</ShipmentBoxWeight>
            <Contents>
              <Content>
                <BarCode>8719829088589</BarCode>
              </Content>
            </Contents>
          </Box>
        </Boxes>
</ShipmentInstruction>

啊
啊
2.
0000000011
0000000011
1.5
8719829088824
0000000011
0000000011
1.5
8719829088831
0000000011
0000000011
1.5
8719829088848
0000000022
0000000022
7.5
8719829088572
0000000022
0000000022
7.5
8719829088589
这是我需要的输出:

<ShipmentInstruction>
        <CarrierCode>AFH</CarrierCode>
        <CarrierProductCode>AFH</CarrierProductCode>
        <ShipmentNoOfBoxes>2</ShipmentNoOfBoxes>
        <Boxes>
          <Box>
            <ShipmentBoxNr>0000000011</ShipmentBoxNr>
            <ShipmentBoxReference>0000000011</ShipmentBoxReference>
            <ShipmentBoxWeight>1.5</ShipmentBoxWeight>
            <Contents>
              <Content>
                <BarCode>8719829088824</BarCode>
              </Content>
              <Content>
                <BarCode>8719829088831</BarCode>
              </Content>
              <Content>
                <BarCode>8719829088848</BarCode>
              </Content>
            </Contents>
          </Box>
          <Box>
            <ShipmentBoxNr>0000000022</ShipmentBoxNr>
            <ShipmentBoxReference>0000000022</ShipmentBoxReference>
            <ShipmentBoxWeight>7.5</ShipmentBoxWeight>
            <Contents>
              <Content>
                <BarCode>8719829088572</BarCode>
              </Content>
              <Content>
                <BarCode>8719829088589</BarCode>
              </Content>
            </Contents>
          </Box>
        </Boxes>
      </ShipmentInstruction>

啊
啊
2.
0000000011
0000000011
1.5
8719829088824
8719829088831
8719829088848
0000000022
0000000022
7.5
8719829088572
8719829088589
我之前使用的XSLT如下所示:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">

    <xsl:template match="/">
                <xsl:element name="ShipmentInstruction">
                        <xsl:element name="CarrierCode">
                            <xsl:value-of select="//ShipmentInstruction/CarrierCode"/> 
                        </xsl:element>
                        <xsl:element name="CarrierProductCode">
                            <xsl:value-of select="//ShipmentInstruction/CarrierProductCode"/> 
                        </xsl:element>
                        <xsl:element name="ShipmentNoOfBoxes">
                            <xsl:value-of select="//ShipmentInstruction/ShipmentNoOfBoxes"/> 
                        </xsl:element>
                        <xsl:element name="Boxes">
                            <xsl:for-each select="//ShipmentInstruction/Boxes/Box">
                            <xsl:variable name="v1" select="ShipmentBoxNr"/>
                             <xsl:element name="Box">
                             <xsl:variable name="v2" select="ShipmentBoxNr"/>
                                <xsl:element name="ShipmentBoxNr">
                                    <xsl:value-of select="ShipmentBoxNr"/> 
                                </xsl:element>
                                <xsl:element name="ShipmentBoxReference">
                                    <xsl:value-of select="ShipmentBoxReference"/> 
                                </xsl:element>
                                <xsl:element name="ShipmentBoxWeight">
                                    <xsl:value-of select="ShipmentBoxWeight"/> 
                                </xsl:element>
                                    <xsl:element name="Contents">   
                                    <xsl:for-each select="//Contents/Content">
                                        <xsl:element name="Content">
                                            <xsl:element name="Barcode">
                                                <xsl:value-of select="Barcode"/> 
                                            </xsl:element>
                                        </xsl:element>
                                    </xsl:for-each>
                                    </xsl:element>                              
                             </xsl:element>
                            </xsl:for-each>
                        </xsl:element>
                </xsl:element>
    </xsl:template>
</xsl:stylesheet>

您似乎在使用XSLT 2.0,您可以对每个组使用
根据
ShipmentBoxNr
对元素进行分组

试试这个:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0">

<xsl:output method="xml" indent="yes" />
<xsl:strip-space elements="*" />

<xsl:template match="/">
    <xsl:element name="ShipmentInstruction">
        <xsl:element name="CarrierCode">
            <xsl:value-of select="//ShipmentInstruction/CarrierCode" />
        </xsl:element>
        <xsl:element name="CarrierProductCode">
            <xsl:value-of select="//ShipmentInstruction/CarrierProductCode" />
        </xsl:element>
        <xsl:element name="ShipmentNoOfBoxes">
            <xsl:value-of select="//ShipmentInstruction/ShipmentNoOfBoxes" />
        </xsl:element>
        <xsl:element name="Boxes">
            <xsl:for-each-group select="ShipmentInstruction/Boxes/Box"
                group-by="ShipmentBoxNr">

                <xsl:element name="Box">
                    <xsl:element name="ShipmentBoxNr">
                        <xsl:value-of select="ShipmentBoxNr" />
                    </xsl:element>
                    <xsl:element name="ShipmentBoxReference">
                        <xsl:value-of select="ShipmentBoxReference" />
                    </xsl:element>
                    <xsl:element name="ShipmentBoxWeight">
                        <xsl:value-of select="ShipmentBoxWeight" />
                    </xsl:element>
                    <xsl:element name="Contents">
                        <xsl:for-each-group select="current-group()/Contents/Content" group-starting-with="BarCode">
                            <xsl:copy-of select="current-group()" />
                        </xsl:for-each-group>
                    </xsl:element>
                </xsl:element>
            </xsl:for-each-group>
        </xsl:element>
    </xsl:element>
</xsl:template>
</xsl:stylesheet>

请参见此处的演示:

或简单地:

XSLT2.0

<xsl:stylesheet version="2.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="*"/>

<!-- identity transform -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="Boxes">
    <xsl:copy>
        <xsl:for-each-group select="Box" group-by="ShipmentBoxNr">
            <Box>
                <xsl:copy-of select="* except Contents"/>
                <Contents>
                    <xsl:copy-of select="current-group()/Contents/Content"/>
                </Contents>
            </Box>
        </xsl:for-each-group>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

请对您要完成的任务添加简短的说明。这似乎是一个简单的分组问题,在XSLT2.0中并不重要。