【问题标题】:Transformation from flat to nested XML in XSLT 1.0XSLT 1.0 中从平面到嵌套 XML 的转换
【发布时间】:2019-10-24 11:24:33
【问题描述】:

我有以下平面 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>

我需要以下结果。 每个&lt;Tax&gt; 元素必须移动到正确的&lt;Item&gt; 内(具有相同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>

我认为使用以下 XSLT 可以轻松获得所需的内容(XSLT 版本 1.0 是必须的),但 &lt;Tax&gt; 元素从未出现。

我尝试了很多更改,但没有一个是正确的。

我还发现了很多“平面到嵌套 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>

非常感谢您的帮助。

【问题讨论】:

    标签: xml xslt xslt-1.0


    【解决方案1】:

    我建议您使用key 来检索匹配的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>
    

    【讨论】:

    • 非常感谢迈克尔的回复。不幸的是,我拼错了一个税元素名称(匹配项应该是从 Item/rowNumber 到 Tax/taxRowNumber)。使用 方法仍然可以得到结果吗?
    • 使用&lt;xsl:key name="tax" match="Tax" use="concat(Number, '|', taxRowNumber)" /> 它也适用于 之间的不同元素名称。再次感谢!
    • 是的,这是一个微不足道的调整。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多