2012-05-16 64 views
0

排序獨特值I具有以下簡化的XML結構:XSLT 1.0:用密鑰,但有例外

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

但現在我怎麼能定義密鑰,所以我將「收益中心」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是我想要做什麼,我使用兩個不同的密鑰:

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

此解決方案的工作原因我知道我需要排除和分組。

我很欣賞任何意見或增強 - 謝謝。

最好的問候, 彼得

回答

1

你想要的東西分類和/或以特定方式要放眼生成「排序鍵」的組合任何時候。在您生成索引的位置

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

您需要提供一個函數,用於從相應的參數生成所需的鍵。在索引中查找鍵時,您可以使用相同的功能。

在XSLT 1中,您可以使用EXSLT func:function來重新打包邏輯。

如果您對Java很熟悉,這就像是定義一個自定義Comparator

+0

你好吉姆,我一直在嘗試。我的問題是如何創建密鑰。我已經嘗試過了:''and 僅處理記錄爲「收益中心」= 9992並處理剩下的事情。但這些鍵不起作用。我假設在密鑰中使用「contains()」是錯誤的方法。我怎麼能在這裏區分?再次感謝你,彼得 – Peter

+0

你好吉姆,我更新了我的問題,我發現了一個XSLT,可以滿足我的需求。最好的祝福, – Peter