【问题标题】:Group XML Elements based on element values and attributes using XSLT 2.0使用 XSLT 2.0 根据元素值和属性对 XML 元素进行分组
【发布时间】:2015-07-09 20:55:55
【问题描述】:

我想遍历 XML 元素,通过一个公共元素值对数据进行分组。 输入的 XML 结构是:

<?xml version="1.0" encoding="utf-8"?>
<Data>
<output outputType="CORRECTION">
    <row nodeName="ORDER_HEADER" tableName="ORDER_HEADER">
        <column columnName="ORDER_NUMBER">00001</column>
        <column columnName="Country">England</column>
        <column columnName="City">London</column>
    </row>
    <row nodeName="ORDER_HEADER" tableName="ORDER_HEADER">
        <column columnName="ORDER_NUMBER">00002</column>
        <column columnName="Country">England</column>
        <column columnName="City">Birmingham</column>
    </row>
    <row nodeName="ORDER_DETAIL" tableName="ORDER_DETAIL">
        <column columnName="ORDER_NUMBER">00001</column>
        <column columnName="Book">Gone with the wind</column>
        <column columnName="Qty">2</column>
    </row>
    <row nodeName="ORDER_DETAIL" tableName="ORDER_DETAIL">
        <column columnName="ORDER_NUMBER">00001</column>
        <column columnName="Book">Pride and Prejudice</column>
        <column columnName="Qty">3</column>
    </row>
    <row nodeName="ORDER_DETAIL" tableName="ORDER_DETAIL">
        <column columnName="ORDER_NUMBER">00002</column>
        <column columnName="Book">Jane Eyre</column>
        <column columnName="Qty">1</column>
    </row>
</output>
</Data>

我正在尝试创建以下输出:

<Transmission xmlns:xs="http://www.w3.org/2001/XMLSchema"
          xmlns="http://www.w3.org/1999/xhtml">
    <OrderNumber>00001</OrderNumber>
    <Country>England</Country>
    <City>London</CITY>
    <Book>Gone with the wind</Book>
    <QTY>2</QTY>
    <Book>Pride and Prejudice</Book>
    <QTY>3</QTY>
    <OrderNumber>00002</OrderNumber>
    <Country>England</Country>
    <City>Birmingham</CITY>
    <Book>Jane Eyre</Book>
    <QTY>1</QTY>
</Transmission>

这是我目前拥有的 XSL:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0"     xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://www.w3.org/1999/xhtml">
<xsl:output method="xml"  indent="yes" omit-xml-declaration="yes"/>
<xsl:template match="/Data/output[@outputType='CORRECTION']">
    <Transmission>
        <xsl:for-each select="row[@tableName='ORDER_HEADER']">
            <OrderNumber>
                <xsl:value-of select="column[@columnName='ORDER_NUMBER']" />
            </OrderNumber>
            <Country>
                <xsl:value-of select="column[@columnName='Country']" />
            </Country>
            <City>
                <xsl:value-of select="column[@columnName='City']" />
            </City>
        </xsl:for-each>
    </Transmission>
</xsl:template>
</xsl:stylesheet>

我可以从每个订单标题中输出详细信息,但看不到如何选择和分组正确的订单详细信息。任何帮助将不胜感激。

谢谢

【问题讨论】:

    标签: xml xslt


    【解决方案1】:

    您可以使用键来查找订单详细信息(在 XSLT 1.0 和 XSLT 2.0 中都可以使用)

    <xsl:key name="detail" match="row[@nodeName='ORDER_DETAIL']" use="column[@columnName='ORDER_NUMBER']" />
    

    然后,要获取给定订单号的订单详细信息,您可以使用如下键:

    <xsl:for-each select="key('detail', column[@columnName='ORDER_NUMBER'])">
    

    试试这个 XSLT

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml"  indent="yes" omit-xml-declaration="yes"/>
    <xsl:key name="detail" match="row[@nodeName='ORDER_DETAIL']" use="column[@columnName='ORDER_NUMBER']" />
    <xsl:template match="/Data/output[@outputType='CORRECTION']">
        <Transmission>
            <xsl:for-each select="row[@tableName='ORDER_HEADER']">
                <xsl:variable name="orderNumber" select="column[@columnName='ORDER_NUMBER']" />
                <OrderNumber>
                    <xsl:value-of select="$orderNumber" />
                </OrderNumber>
                <Country>
                    <xsl:value-of select="column[@columnName='Country']" />
                </Country>
                <City>
                    <xsl:value-of select="column[@columnName='City']" />
                </City>
                <xsl:apply-templates select="key('detail', $orderNumber)" />
            </xsl:for-each>
        </Transmission>
    </xsl:template>
    
    <xsl:template match="row">
        <Book>
            <xsl:value-of select="column[@columnName='Book']" />
        </Book>
        <QTY>
            <xsl:value-of select="column[@columnName='Qty']" />
        </QTY>
    </xsl:template>
    </xsl:stylesheet>
    

    注意,我改用xsl:apply-templates,只是为了减少过多的嵌套代码。我还使用了一个变量,以避免重复获取订单号。

    顺便说一句,这真的是您想要的 XML 输出吗?像这样将每个订单包装在包含父元素中可能更合乎逻辑,否则为订单提取书籍变得更加困难。

    <Transmission>
     <Order>
       <OrderNumber>00001</OrderNumber>
       <Country>England</Country>
       <City>London</City>
       <Book>Gone with the wind</Book>
       <QTY>2</QTY>
       <Book>Pride and Prejudice</Book>
       <QTY>3</QTY>
     </Order>
     <Order>
       <OrderNumber>00002</OrderNumber>
       <Country>England</Country>
       <City>Birmingham</City>
       <Book>Jane Eyre</Book>
       <QTY>1</QTY>
     </Order>
    </Transmission>
    

    【讨论】:

    • 完美!非常感谢您提供清晰简洁的解决方案。这帮助很大。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-09-02
    • 2016-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-10
    相关资源
    最近更新 更多