【问题标题】:XSLT 1.0 添加每组递增的行号
【发布时间】:2022-01-15 09:46:01
【问题描述】:

我有想要转换的平面 XML 数据,包括按日期值排序和添加递增的行号。

我有以下 XML:

    <?xml version="1.0" encoding="utf-8"?>
<NewDataSet>
    <_x0037_906aa9f-c0f8-4909-baa9-ba3090d6c6e5>
        <InceptionDate>01/01/2021</InceptionDate>
        <FirstName>Fred</FirstName>
        <UMR>A</UMR>
    </_x0037_906aa9f-c0f8-4909-baa9-ba3090d6c6e5>
    <_x0037_906aa9f-c0f8-4909-baa9-ba3090d6c6e5>
        <InceptionDate>02/02/2021</InceptionDate>
        <FirstName>Theo</FirstName>         
        <UMR>A</UMR>
    </_x0037_906aa9f-c0f8-4909-baa9-ba3090d6c6e5>
    <_x0037_906aa9f-c0f8-4909-baa9-ba3090d6c6e5>
        <InceptionDate>03/03/2021</InceptionDate>
        <FirstName>Laura</FirstName>            
        <UMR>A</UMR>
    </_x0037_906aa9f-c0f8-4909-baa9-ba3090d6c6e5>
    <_x0037_906aa9f-c0f8-4909-baa9-ba3090d6c6e5>
        <InceptionDate>01/01/2021</InceptionDate>
        <FirstName>Sarah</FirstName>        
        <UMR>B</UMR>
    </_x0037_906aa9f-c0f8-4909-baa9-ba3090d6c6e5>
    <_x0037_906aa9f-c0f8-4909-baa9-ba3090d6c6e5>
        <InceptionDate>02/02/2021</InceptionDate>
        <FirstName>Gary</FirstName>         
        <UMR>B</UMR>
    </_x0037_906aa9f-c0f8-4909-baa9-ba3090d6c6e5>
    <_x0037_906aa9f-c0f8-4909-baa9-ba3090d6c6e5>
        <InceptionDate>03/03/2021</InceptionDate>
        <FirstName>Bob</FirstName>          
        <UMR>B</UMR>
    </_x0037_906aa9f-c0f8-4909-baa9-ba3090d6c6e5>
</NewDataSet>

我需要转换成以下格式:

<Instances>
   <Instance>
      <formdata>
         <data>
            <UMR>A</UMR>
            <Table TableId="Details">
               <TableRow RowNumber="">
                  <InceptionDate>01/01/2021</InceptionDate>
                  <FirstName>Fred</FirstName>
               </TableRow>
               <TableRow RowNumber="">
                  <InceptionDate>02/02/2021</InceptionDate>
                  <FirstName>Theo</FirstName>
               </TableRow>
               <TableRow RowNumber="">
                  <InceptionDate>03/03/2021</InceptionDate>
                  <FirstName>Laura</FirstName>
               </TableRow>
            </Table>
         </data>
      </formdata>
   </Instance>
   <Instance>
      <formdata>
         <data>
            <UMR>B</UMR>
            <Table TableId="Details">
               <TableRow RowNumber="">
                  <InceptionDate>01/01/2021</InceptionDate>
                  <FirstName>Sarah</FirstName>
               </TableRow>
               <TableRow RowNumber="">
                  <InceptionDate>02/02/2021</InceptionDate>
                  <FirstName>Gary</FirstName>
               </TableRow>
               <TableRow RowNumber="">
                  <InceptionDate>03/03/2021</InceptionDate>
                  <FirstName>Bob</FirstName>
               </TableRow>
            </Table>
         </data>
      </formdata>
   </Instance>
</Instances>

我有以下 XSLT 样式表:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

<!-- set up the key. -->
    <xsl:key name="UMRItems" match="NewDataSet/*" use="UMR"/>

    <!-- Matches the whole dataset and creates a copy-->
    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>

    <!-- Matches NewDataSet element and replaces with Instances element -->
    <xsl:template match="NewDataSet">
        <Instances>
            <xsl:apply-templates select="*[generate-id(.)=generate-id(key('UMRItems', UMR)[1])]"/>
        </Instances>    
    </xsl:template>

    <!-- Matches the GUID element and replaces with Instance element -->
    <xsl:template match="NewDataSet/*">
        <Instance>
            <formdata>
                <data>
                    <!-- Selects non-table form data -->
                    <UMR><xsl:value-of select="UMR"/></UMR>
        
                    <Table>
                        <xsl:attribute name="TableId">
                            <xsl:text>Details</xsl:text>
                        </xsl:attribute>
                    
                        <xsl:for-each select="key('UMRItems', UMR)">
                        <xsl:sort select="InceptionDate"/>
                            <xsl:call-template name="TableDetails"></xsl:call-template>

                        </xsl:for-each>
                    </Table>    
                </data>
            </formdata>
        </Instance> 
    </xsl:template>
    <xsl:template name="TableDetails">
            <TableRow RowNumber="" > 
                <InceptionDate><xsl:value-of select="InceptionDate"/></InceptionDate>
                <FirstName><xsl:value-of select="FirstName"/></FirstName>
            </TableRow>
    </xsl:template>
</xsl:stylesheet>

但我希望得到以下输出:

<Instances>
   <Instance>
      <formdata>
         <data>
            <UMR>A</UMR>
            <Table TableId="Details">
               <TableRow RowNumber="1">
                  <InceptionDate>01/01/2021</InceptionDate>
                  <FirstName>Fred</FirstName>
               </TableRow>
               <TableRow RowNumber="2">
                  <InceptionDate>02/02/2021</InceptionDate>
                  <FirstName>Theo</FirstName>
               </TableRow>
               <TableRow RowNumber="3">
                  <InceptionDate>03/03/2021</InceptionDate>
                  <FirstName>Laura</FirstName>
               </TableRow>
            </Table>
         </data>
      </formdata>
   </Instance>
   <Instance>
      <formdata>
         <data>
            <UMR>B</UMR>
            <Table TableId="Details">
               <TableRow RowNumber="1">
                  <InceptionDate>01/01/2021</InceptionDate>
                  <FirstName>Sarah</FirstName>
               </TableRow>
               <TableRow RowNumber="2">
                  <InceptionDate>02/02/2021</InceptionDate>
                  <FirstName>Gary</FirstName>
               </TableRow>
               <TableRow RowNumber="3">
                  <InceptionDate>03/03/2021</InceptionDate>
                  <FirstName>Bob</FirstName>
               </TableRow>
            </Table>
         </data>
      </formdata>
   </Instance>
</Instances>

但是我无法生成应按表递增的行号。

我尝试过使用:

 Position()  

但这会导致所有 RowNumbers = 1

count(preceding::UMR[(preceding::UMR= .)])+1

这似乎更接近,但只会增加第 1 行和第 2 行。

谢谢

【问题讨论】:

    标签: xml xslt


    【解决方案1】:

    你为什么不简单地做:

    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:key name="UMRItems" match="/NewDataSet/*" use="UMR"/>
    
    <xsl:template match="/NewDataSet">
        <Instances>
            <!-- a group for each distinct UMR value  -->
            <xsl:for-each select="*[generate-id(.)=generate-id(key('UMRItems', UMR)[1])]">
                <Instance>
                    <formdata>
                        <data>
                            <xsl:copy-of select="UMR"/>
                            <Table TableId="Details">
                                <!-- a row for each member of current group  -->
                                <xsl:for-each select="key('UMRItems', UMR)">
                                    <TableRow RowNumber="{position()}">
                                        <xsl:copy-of select="InceptionDate | FirstName"/>
                                    </TableRow>
                                </xsl:for-each>
                            </Table>
                        </data>
                    </formdata>
                </Instance>
            </xsl:for-each>
        </Instances>    
    </xsl:template>
    
    </xsl:stylesheet>
    

    【讨论】:

    • 谢谢!这解决了我的问题。我非常感谢您的快速回复,这是我已经尝试了一段时间的事情了!
    • 请注意,如果您在TableDetails 模板中包含&lt;TableRow RowNumber="{position()}"&gt;,您的样式表也会起作用。但是没有充分的理由拥有所有这些额外的代码。
    猜你喜欢
    • 2016-02-08
    • 1970-01-01
    • 2016-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-03
    • 2016-04-23
    • 1970-01-01
    相关资源
    最近更新 更多