Преобразование из плоского во вложенный XML в XSLT 1.0 - PullRequest
0 голосов
/ 24 октября 2019

У меня следующая плоская структура 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>

И мне нужен следующий результат. Каждый <Tax> элемент должен быть перемещен внутри правильного <Item> (элемента с одинаковой Number и rowNumber информацией)

<?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>

Я думал, что легко смогу получить то, что мне нужно, с помощьюследующий XSLT ( XSLT версии 1.0 является обязательным ), но элемент <Tax> никогда не появляется.

Я перепробовал много изменений, но ни одно из них не является правильным.

Я также нашелмного «простых» вложенных вопросов 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>

Большое спасибо за любую помощь.

1 Ответ

1 голос
/ 24 октября 2019

Я бы посоветовал вам использовать ключ для получения соответствующих Tax узлов. Попробуйте:

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>
...