简体   繁体   English

XSLT 1.0 中从平面到嵌套 XML 的转换

[英]Transformation from flat to nested XML in XSLT 1.0

I have the following flat xml structure我有以下平面 xml 结构

<?xml version="1.0" encoding="UTF-8"?>
<ns0:Main xmlns:ns0="urn:test">
    <RECORDSET>
        <Item>
            <Number>00011111</Number>
            <rowNumber>00001</rowNumber>
            <Product>Product 1</Product>
        </Item>
        <Item>
            <Number>00011111</Number>
            <rowNumber>00002</rowNumber>
            <Product>Product 2</Product>
        </Item>
        <Item>
            <Number>00099999</Number>
            <rowNumber>00001</rowNumber>
            <Product>Product 3</Product>
        </Item>
        <Tax>
            <Number>00011111</Number>
            <taxRowNumber>00001</taxRowNumber>
            <TaxType>TAX1</TaxType>
            <Amount>100</Amount>
        </Tax>
        <Tax>
            <Number>00011111</Number>
            <taxRowNumber>00001</taxRowNumber>
            <TaxType>TAX2</TaxType>
            <Amount>200</Amount>
        </Tax>
        <Tax>
            <Number>00099999</Number>
            <taxRowNumber>00001</taxRowNumber>
            <TaxType>TAX2</TaxType>
            <Amount>110</Amount>
        </Tax>
    </RECORDSET>
</ns0:Main>

And I need the following result.我需要以下结果。 Each <Tax> element must be moved inside the proper <Item> (The one with the the same Number and rowNumber informations)每个<Tax>元素必须移动到正确的<Item>内(具有相同NumberrowNumber信息的元素)

<?xml version="1.0" encoding="UTF-8"?>
<ns0:Main xmlns:ns0="urn:test">
    <RECORDSET>
        <Item>
            <Number>00011111</Number>
            <rowNumber>00001</rowNumber>
            <Product>Product 1</Product>
            <Tax>
                <Number>00011111</Number>
                <taxRowNumber>00001</taxRowNumber>
                <TaxType>TAX1</TaxType>
                <Amount>100</Amount>
            </Tax>
            <Tax>
                <Number>00011111</Number>
                <taxRowNumber>00001</taxRowNumber>
                <TaxType>TAX2</TaxType>
                <Amount>200</Amount>
            </Tax>
        </Item>
        <Item>
            <Number>00011111</Number>
            <rowNumber>00002</rowNumber>
            <Product>Product 2</Product>
        </Item>
        <Item>
            <Number>00099999</Number>
            <rowNumber>00001</rowNumber>
            <Product>Product 3</Product>
            <Tax>
                <Number>00099999</Number>
                <taxRowNumber>00001</taxRowNumber>
                <TaxType>TAX2</TaxType>
                <Amount>110</Amount>
            </Tax>
        </Item>
    </RECORDSET>
</ns0:Main>

I thought I could easily get what I need with the following XSLT ( XSLT version 1.0 is a must ), but the <Tax> element never appear.我想我可以通过以下 XSLT 轻松获得我需要的东西( XSLT 版本 1.0 是必须的),但<Tax>元素永远不会出现。

I tried many changes but none is correct.我尝试了很多更改,但没有一个是正确的。

I also found a lot of "flat to nested XML" questions, but without luck我还发现了很多“平面到嵌套 XML”的问题,但没有运气

<?xml version="1.0"?>
<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns0="urn:test">
    <xsl:output method="xml" indent="yes"/>
    <xsl:template match="/">
        <ns0:Main>
            <RECORDSET>
                <xsl:for-each select="ns0:Main/RECORDSET/Item">
                    <Item>
                        <xsl:for-each select="Number">
                            <Number>
                                <xsl:value-of select="."/>
                            </Number>
                        </xsl:for-each>
                        <xsl:for-each select="rowNumber">
                            <rowNumber>
                                <xsl:value-of select="."/>
                            </rowNumber>
                        </xsl:for-each>
                        <xsl:for-each select="Product">
                            <Product>
                                <xsl:value-of select="."/>
                            </Product>
                        </xsl:for-each>
                        <xsl:variable name="KeyNumber" select="Number"/>
                        <xsl:variable name="KeyrowNumber" select="rowNumber"/>
                        <xsl:for-each select="ns0:Main/RECORDSET/Tax[ Number    = $KeyNumber and
                                                                      taxRowNumber = $KeyrowNumber ]">
                            <Tax>
                                <xsl:copy-of select="./*"/>
                            </Tax>
                        </xsl:for-each>
                    </Item>
                </xsl:for-each>
            </RECORDSET>
        </ns0:Main>
    </xsl:template>
</xsl:transform>

Thanks a lot for any help.非常感谢您的帮助。

I would suggest you use a key to retrieve the matching Tax nodes.我建议您使用密钥来检索匹配的Tax节点。 Try:尝试:

XSLT 1.0 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="tax" match="Tax" use="concat(Number, '|', taxRowNumber)" />

<xsl:template match="/*">
    <xsl:copy>
        <RECORDSET>
            <xsl:for-each select="RECORDSET/Item">
                <xsl:copy>
                    <xsl:copy-of select="*"/>
                    <xsl:copy-of select="key('tax', concat(Number, '|', rowNumber))"/>
                </xsl:copy>
            </xsl:for-each>
        </RECORDSET>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM