Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
XSLT1.0:使用键对唯一值进行排序,但有例外_Xslt_Xslt Grouping_Muenchian Grouping - Fatal编程技术网

XSLT1.0:使用键对唯一值进行排序,但有例外

XSLT1.0:使用键对唯一值进行排序,但有例外,xslt,xslt-grouping,muenchian-grouping,Xslt,Xslt Grouping,Muenchian Grouping,我有以下简化的XML结构: <?xml version="1.0" encoding="UTF-8"?> <ExportData> <DataSet> <Tables> <Table> <Rows> <R> <transactionQualifierstring>Sales</

我有以下简化的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>

销售额
9991
销售额
9993
销售额
9992
销售额
9994
销售额
9995
销售额
销售额
9993
我需要根据“限定符字符串”和“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个键) 或者可以使用值扩展现有键吗

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>

销售额
9991
销售额
9993
销售额
9993
销售额
9992
销售额
9994
销售额
9995
销售额
谢谢你的任何提示或想法

致以最良好的祝愿, 彼得

2012年5月24日更新: 实际上,我提出了一个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)"/>-->
<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>

销售额
9991
销售额
9994
销售额
9995
销售额
销售额
9993
销售额
9992
销售额
9993
此解决方案之所以有效,是因为我知道需要排除哪些值并分别分组

我非常感谢您的任何意见或改进-谢谢

致以最良好的祝愿,
Peter

每当您希望以特定方式对事物进行排序和/或分组时,考虑生成“排序键”会有所帮助。在生成索引的位置

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

您需要提供一个函数,从适当的参数生成所需的键。然后在索引中查找键时使用相同的函数

在XSLT1中,可以使用EXSLT
func:function
对逻辑进行可重用的打包


如果您熟悉Java,这有点像定义自定义的
比较器

你好,Jim,我一直在尝试。我的问题是如何创建密钥。我尝试过:``只处理“revenueCenter”=9992的记录,并处理其余的记录。但这些钥匙不起作用。我认为在键中使用“contains()”是错误的方法。我在这里怎么区分?再次感谢您,PeterHello Jim,我更新了我的问题,找到了一个满足我需要的XSLT。顺致敬意,