0

私は次の単純化されたXML構造を持っています:

<?xml version="1.0" encoding="UTF-8"?>
<ExportData>
<DataSet>
    <Tables>
        <Table>
            <Rows>
                <R>
                    <transactionQualifierstring>Sales</transactionQualifierstring>
                    <revenueCenterPOSReflongtrue>9991</revenueCenterPOSReflongtrue>
                </R>
                <R>
                    <transactionQualifierstring>Sales</transactionQualifierstring>
                    <revenueCenterPOSReflongtrue>9993</revenueCenterPOSReflongtrue>
                </R>
                <R>
                    <transactionQualifierstring>Sales</transactionQualifierstring>
                    <revenueCenterPOSReflongtrue>9992</revenueCenterPOSReflongtrue>
                </R>
                <R>
                    <transactionQualifierstring>Sales</transactionQualifierstring>
                    <revenueCenterPOSReflongtrue>9994</revenueCenterPOSReflongtrue>
                </R>
                <R>
                    <transactionQualifierstring>Sales</transactionQualifierstring>
                    <revenueCenterPOSReflongtrue>9995</revenueCenterPOSReflongtrue>
                </R>
                <R>
                    <transactionQualifierstring>Sales</transactionQualifierstring>
                    <revenueCenterPOSReflongtrue/>
                </R>
                <R>
                    <transactionQualifierstring>Sales</transactionQualifierstring>
                    <revenueCenterPOSReflongtrue>9993</revenueCenterPOSReflongtrue>
                </R>
            </Rows>
        </Table>
    </Tables>
</DataSet>
</ExportData>

「Qualifierstring」と「revenueCenter」に応じてレコードセット(R)をグループ化する必要があります。私は完璧に機能するこのXSLTを思いついた:

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

<xsl:output method="xml" indent="yes"/>
<xsl:template match="text()|@*"/>

<!-- define the key to define unique elements -->
<xsl:key name="keyTranstypeCcRc" match="R" use="concat(transactionQualifierstring,'|',revenueCenterPOSReflongtrue)"/>

<!-- define which elements are unique -->
<xsl:template match="ExportData/DataSet/Tables/Table/Rows">
    <xsl:variable name="uniqueTransactions" select="R[generate-id()=generate-id(key('keyTranstypeCcRc',concat(transactionQualifierstring,'|',revenueCenterPOSReflongtrue))[1])]"/>
    <ExportData>
        <xsl:apply-templates select="$uniqueTransactions" mode="group"/>
    </ExportData>
</xsl:template>

<!-- create the unique groups -->
<xsl:template match="R" mode="group">
    <transaction>
        <xsl:attribute name="transactionType"><!-- write the 2 key criteria into this attribute -->
            <xsl:value-of select="concat(transactionQualifierstring,'|',revenueCenterPOSReflongtrue)"/>
        </xsl:attribute>
        <xsl:apply-templates select="key('keyTranstypeCcRc', concat(transactionQualifierstring,'|',revenueCenterPOSReflongtrue))" mode="item"/>
    </transaction>
</xsl:template>

<!-- write the item content into each group -->
<xsl:template match="R" mode="item">
    <R>
        <xsl:copy-of select="child::*"/> 
    </R>
</xsl:template>

</xsl:stylesheet>

キーを定義して一意のアイテムを選択し、グループを作成してレコードセット(R)を処理します。

しかし、「revenueCenter」9992と9993をグループ化するために、どのようにキーを定義できますか?2つの異なるキーを設定する必要がありますか?(ただし、テンプレートで2つのキーを使用するにはどうすればよいですか)または、既存のキーを値で拡張できますか?

XMLは次のようになります。

<?xml version="1.0" encoding="UTF-8"?>
<ExportData>
<transaction transactionType="Sales|9991">
    <R>
        <transactionQualifierstring>Sales</transactionQualifierstring>
        <revenueCenterPOSReflongtrue>9991</revenueCenterPOSReflongtrue>
    </R>
</transaction>
<transaction transactionType="Sales|9993 Sales|9992">
    <R>
        <transactionQualifierstring>Sales</transactionQualifierstring>
        <revenueCenterPOSReflongtrue>9993</revenueCenterPOSReflongtrue>
    </R>
    <R>
        <transactionQualifierstring>Sales</transactionQualifierstring>
        <revenueCenterPOSReflongtrue>9993</revenueCenterPOSReflongtrue>
    </R>
    <R>
        <transactionQualifierstring>Sales</transactionQualifierstring>
        <revenueCenterPOSReflongtrue>9992</revenueCenterPOSReflongtrue>
    </R>
</transaction>
<transaction transactionType="Sales|9994">
    <R>
        <transactionQualifierstring>Sales</transactionQualifierstring>
        <revenueCenterPOSReflongtrue>9994</revenueCenterPOSReflongtrue>
    </R>
</transaction>
<transaction transactionType="Sales|9995">
    <R>
        <transactionQualifierstring>Sales</transactionQualifierstring>
        <revenueCenterPOSReflongtrue>9995</revenueCenterPOSReflongtrue>
    </R>
</transaction>
<transaction transactionType="Sales|">
    <R>
        <transactionQualifierstring>Sales</transactionQualifierstring>
        <revenueCenterPOSReflongtrue/>
    </R>
</transaction>
</ExportData>

2012年5月24日更新: 私は実際に私が望むことを行うXSLTを思いついた、私は2つの異なるキーを使用している:

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

<xsl:output method="xml" indent="yes"/>
<xsl:template match="text()|@*"/>


<!-- define the key to define unique elements -->
<!--<xsl:key name="keyTranstypeCcRc" match="R" use="concat(transactionQualifierstring,'|',revenueCenterPOSReflongtrue)"/>-->
<xsl:key name="keyTranstypeCcRc" match="R[not(revenueCenterPOSReflongtrue='9992' or revenueCenterPOSReflongtrue='9993')]" 
    use="concat(transactionQualifierstring,'|',revenueCenterPOSReflongtrue)"/>

<xsl:key name="keyTranstypeCcRc99923" match="R[revenueCenterPOSReflongtrue='9992' or revenueCenterPOSReflongtrue='9993']" 
    use="transactionQualifierstring"/>

<!-- define which elements are unique -->
<xsl:template match="ExportData/DataSet/Tables/Table/Rows">
    <xsl:variable name="uniqueTransactions" select="R[not(revenueCenterPOSReflongtrue='9992' or revenueCenterPOSReflongtrue='9993')]
        [generate-id()=generate-id(key('keyTranstypeCcRc',concat(transactionQualifierstring,'|',revenueCenterPOSReflongtrue))[1])]"/>
    <xsl:variable name="keyTranstypeCcRc99923" select="R[revenueCenterPOSReflongtrue='9992' or revenueCenterPOSReflongtrue='9993']
        [generate-id()=generate-id(key('keyTranstypeCcRc99923',transactionQualifierstring)[1])]"/>
    <ExportData>
        <xsl:apply-templates select="$uniqueTransactions" mode="group"/>
        <xsl:apply-templates select="$keyTranstypeCcRc99923" mode="group99923"/>
    </ExportData>
</xsl:template>

<!-- create the unique groups -->
<xsl:template match="R" mode="group">
    <transaction>
        <xsl:attribute name="transactionType"><!-- write the 2 key criteria into this attribute -->
            <xsl:value-of select="concat(transactionQualifierstring,'|',revenueCenterPOSReflongtrue)"/>
        </xsl:attribute>
        <xsl:apply-templates select="key('keyTranstypeCcRc', concat(transactionQualifierstring,'|',revenueCenterPOSReflongtrue))" mode="item"/>
        
    </transaction>
</xsl:template>

<!-- create the unique groups -->
<xsl:template match="R" mode="group99923">
    <transaction>
        <xsl:attribute name="transactionType"><!-- write the 2 key criteria into this attribute -->
            <xsl:value-of select="concat(transactionQualifierstring,'|','9992','|','9993')"/>
        </xsl:attribute>
        <xsl:apply-templates select="key('keyTranstypeCcRc99923', transactionQualifierstring)" mode="item"/>
        
    </transaction>
</xsl:template>

<!-- write the item content into each group -->
<xsl:template match="R" mode="item">
    <R>
        <xsl:copy-of select="child::*"/> 
    </R>
</xsl:template>

</xsl:stylesheet>

ソースXMLに適用すると、次の正しい出力が得られます。

<?xml version="1.0" encoding="UTF-8"?>
<ExportData>
<transaction transactionType="Sales|9991">
    <R>
        <transactionQualifierstring>Sales</transactionQualifierstring>
        <revenueCenterPOSReflongtrue>9991</revenueCenterPOSReflongtrue>
    </R>
</transaction>
<transaction transactionType="Sales|9994">
    <R>
        <transactionQualifierstring>Sales</transactionQualifierstring>
        <revenueCenterPOSReflongtrue>9994</revenueCenterPOSReflongtrue>
    </R>
</transaction>
<transaction transactionType="Sales|9995">
    <R>
        <transactionQualifierstring>Sales</transactionQualifierstring>
        <revenueCenterPOSReflongtrue>9995</revenueCenterPOSReflongtrue>
    </R>
</transaction>
<transaction transactionType="Sales|">
    <R>
        <transactionQualifierstring>Sales</transactionQualifierstring>
        <revenueCenterPOSReflongtrue/>
    </R>
</transaction>
<transaction transactionType="Sales|9992|9993">
    <R>
        <transactionQualifierstring>Sales</transactionQualifierstring>
        <revenueCenterPOSReflongtrue>9993</revenueCenterPOSReflongtrue>
    </R>
    <R>
        <transactionQualifierstring>Sales</transactionQualifierstring>
        <revenueCenterPOSReflongtrue>9992</revenueCenterPOSReflongtrue>
    </R>
    <R>
        <transactionQualifierstring>Sales</transactionQualifierstring>
        <revenueCenterPOSReflongtrue>9993</revenueCenterPOSReflongtrue>
    </R>
</transaction>
</ExportData>

このソリューションが機能するのは、除外して個別にグループ化する必要がある値がわかっているためです。

4

1 に答える 1

1

特定の方法で物事をソートおよび/またはグループ化したいときはいつでも、「ソートキー」を生成することを考えると役立ちます。インデックスを生成した時点で

<xsl:key name="keyTranstypeCcRc" match="R" use="makeKey(...)"/>

適切な引数から目的のキーを生成する関数を提供する必要があります。次に、インデックスでキーを検索するときに同じ関数を使用します。

XSLT 1では、EXSLTfunc:functionを使用してロジックを再利用可能にパッケージ化できます。

Javaに精通している場合、これはカスタムを定義するようなものComparatorです。

于 2012-05-16T22:05:56.290 に答える