XSLT 用于将平面 XML 与多个嵌套部分分组

问题描述 投票:0回答:1

我想要通过在另一个区域中重复部分 xml 来转换平面 XML 数据。

我有以下 XML:

   <?xml version="1.0" encoding="utf-8"?>
<NewDataSet>
    <GUID>
        <Name>Item1</Name>
        <Status>Open</Status>
        <TableId>Table1</TableId>
    </GUID>
    <GUID>
        <Name>Item2</Name>
        <Status>Closed</Status>
        <TableId>Table1</TableId>
    </GUID>
    <GUID>
        <SignOffName>Fred</SignOffName>
        <Location>UK</Location>
        <TableId>Table2</TableId>
    </GUID>
    <GUID>
        <SignOffName>Mary</SignOffName>
        <Location>UK</Location>
        <TableId>Table2</TableId>
    </GUID>
</NewDataSet>

我需要将其转换为以下格式: 您将看到 TableId = Table2 的位置,它们在 Table1 项目中重复出现。

<Instances>
    <Instance>
        <Name>Item1</Name>
        <data>
            <Status>Open</Status>
            <Table>
                <TableRow RowNumber="1">
                  <SignOffName>Fred<SignOffName>
                  <Location>UK</Location>
               </TableRow>
                <TableRow RowNumber="2">
                  <SignOffName>Mary<SignOffName>
                  <Location>UK</Location>
               </TableRow>
            </Table>
        </data>
    </Instance>
    <Instance>
        <Name>Item2</Name>
        <data>
            <Status>Closed</Status>
            <Table>
                <TableRow RowNumber="1">
                  <SignOffName>Fred<SignOffName>
                  <Location>UK</Location>
               </TableRow>
                <TableRow RowNumber="2">
                  <SignOffName>Mary<SignOffName>
                  <Location>UK</Location>
               </TableRow>
            </Table>
        </data>
    </Instance>
</Instances>

我有以下 XSLT 样式表:

<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:key name="Items" match="/NewDataSet/*" use="Name"/>

<xsl:template match="/NewDataSet">
    <Instances>
        <xsl:for-each select="*[generate-id(.)=generate-id(key('Items', Name)[1])]">
            <Instance>
                <xsl:copy-of select="Name"/>
                <formdata>
                    <data>
                        <xsl:copy-of select="Status"/>
                        <Table>
                            <!-- a row for each member of current group  -->
                            <xsl:for-each select="key('Items', Name)">
                                <TableRow RowNumber="{position()}">
                                    <xsl:copy-of select="SignOffName | Location"/>
                                </TableRow>
                            </xsl:for-each>
                        </Table>
                    </data>
                </formdata>
            </Instance>
        </xsl:for-each>
    </Instances>    
</xsl:template>

</xsl:stylesheet>

但我期望以下输出:

<Instances>
    <Instance>
        <Name>Item1</Name>
        <data>
            <Status>Open</Status>
            <Table>
                <TableRow RowNumber="1">
                  <SignOffName>Fred<SignOffName>
                  <Location>UK</Location>
               </TableRow>
                <TableRow RowNumber="2">
                  <SignOffName>Mary<SignOffName>
                  <Location>UK</Location>
               </TableRow>
            </Table>
        </data>
    </Instance>
    <Instance>
        <Name>Item2</Name>
        <data>
            <Status>Closed</Status>
            <Table>
                <TableRow RowNumber="1">
                  <SignOffName>Fred<SignOffName>
                  <Location>UK</Location>
               </TableRow>
                <TableRow RowNumber="2">
                  <SignOffName>Mary<SignOffName>
                  <Location>UK</Location>
               </TableRow>
            </Table>
        </data>
    </Instance>
</Instances>

我不知道如何访问其他项目,因为它们不在当前组中。

谢谢

xml xslt-1.0
1个回答
0
投票

我不太明白你转变的逻辑。难道不能简单地通过以下方式产生预期的结果:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>

<xsl:template match="NewDataSet">
    <Instances>
        <xsl:for-each select="GUID[TableId='Table1']">
            <Instance>
                <xsl:copy-of select="Name"/>
                <data>
                    <xsl:copy-of select="Status"/>
                    <Table>
                        <xsl:for-each select="../GUID[TableId='Table2']">
                            <TableRow RowNumber="{position()}">
                                <xsl:copy-of select="SignOffName | Location"/>
                            </TableRow>                 
                        </xsl:for-each>
                    </Table>
                </data>
            </Instance>
        </xsl:for-each>
    </Instances>
</xsl:template>

</xsl:stylesheet>
© www.soinside.com 2019 - 2024. All rights reserved.