2013-04-24 59 views
2

我有一個轉換,我試圖記錄一組扁平事務細節,並在文件末尾提供根據投標類型和註冊編號分組的總和。
記錄單個交易細節的集合是很容易的部分,我工作得很好,但我正在爲總結部分掙扎。xslt 1.0使用複合鍵分組(在不同級別)

問題是,我不知道有什麼或有多少不同的寄存器編號,或者有多少種投標類型(因此在靜態過濾器字符串中明確列出xslt中的摘要是一種不行),所以某種分組似乎是按順序的。

還有一個扳手 - 我堅持使用XSLT 1.0 ...

我試圖與Muenchian分組的插科打諢,但(與寄存器生活在不同的級別比付款方式)化合物關鍵要求之間和我有限瞭解如何muenchian方法和鑰匙工作在第一個地方我似乎無法得到它的工作,但我認爲它仍然可能是需要的技巧...

任何建議,我怎麼可能muenchia - 神奇地得到這個工作?

這裏有一個例子源文件:

<s0:SalesCollection xmlns:s0="http://mySourceSchema"> 
    <s0:Sale transactionnumber="1" register="1"> 
    <s0:Tender amount="1.11" paymentmethod="visa" /> 
    <s0:Tender amount="2.22" paymentmethod="mastercard" /> 
    </s0:Sale> 
    <s0:Sale transactionnumber="2" register="1"> 
    <s0:Tender amount="5.55" paymentmethod="discover" /> 
    <s0:Tender amount="4.44" paymentmethod="visa" /> 
    </s0:Sale> 
    <s0:Sale transactionnumber="1" register="2"> 
    <s0:Tender amount="9.99" paymentmethod="amex" /> 
    <s0:Tender amount="8.88" paymentmethod="visa" /> 
    </s0:Sale> 
</s0:SalesCollection> 

這裏就是我要去的(再次,我有記錄[@類型= '細節']記錄工作的話):

<ns0:root xmlns:ns0="http://myDestinationSchema"> 
    <ns0:record type="detail" transactionnumber="1" register="1" amount="1.11" paymentmethod="visa" /> 
    <ns0:record type="detail" transactionnumber="1" register="1" amount="2.22" paymentmethod="mastercard" /> 
    <ns0:record type="detail" transactionnumber="2" register="1" amount="5.55" paymentmethod="discover" /> 
    <ns0:record type="detail" transactionnumber="2" register="1" amount="4.44" paymentmethod="visa" /> 
    <ns0:record type="detail" transactionnumber="1" register="2" amount="9.99" paymentmethod="amex" /> 
    <ns0:record type="detail" transactionnumber="1" register="2" amount="8.88" paymentmethod="visa" /> 
    <ns0:record type="summary" register="1" amount="5.55" paymentmethod="visa" /> 
    <ns0:record type="summary" register="1" amount="2.22" paymentmethod="mastercard" /> 
    <ns0:record type="summary" register="1" amount="5.55" paymentmethod="discover" /> 
    <ns0:record type="summary" register="2" amount="9.99" paymentmethod="amex" /> 
    <ns0:record type="summary" register="2" amount="8.88" paymentmethod="visa" /> 
</ns0:root> 

那麼我該如何創建使用xslt 1.0按寄存器和付款方法分組的彙總記錄?

回答

3

該轉化

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:s0="http://mySourceSchema" 
xmlns:ns0="http://myDestinationSchema" exclude-result-prefixes="s0"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:key name="kTendByTypeAndReg" match="s0:Tender" 
    use="concat(../@register, '#', @paymentmethod)"/> 

<xsl:template match="/*"> 
    <ns0:root xmlns:ns0="http://myDestinationSchema"> 
    <xsl:apply-templates select="*/*"/> 
    <xsl:apply-templates mode="group" select= 
    "*/*[generate-id() 
     =generate-id(key('kTendByTypeAndReg', 
         concat(../@register, '#', @paymentmethod))[1] 
         ) 
     ]"/> 
    </ns0:root> 
</xsl:template> 

<xsl:template match="s0:Tender"> 
    <ns0:record type="detail" transactionnumber="{../@transactionnumber}" 
     register="{../@register}" amount="{@amount}" paymentmethod="{@paymentmethod}" /> 
</xsl:template> 

<xsl:template match="*" mode="group"> 
    <ns0:record type="summary" register="{../@register}" paymentmethod="{@paymentmethod}" 
    amount="{sum(key('kTendByTypeAndReg',concat(../@register,'#',@paymentmethod)) 
        /@amount)}"/> 
</xsl:template> 
</xsl:stylesheet> 

當所提供的XML文檔應用:

<s0:SalesCollection xmlns:s0="http://mySourceSchema"> 
    <s0:Sale transactionnumber="1" register="1"> 
    <s0:Tender amount="1.11" paymentmethod="visa" /> 
    <s0:Tender amount="2.22" paymentmethod="mastercard" /> 
    </s0:Sale> 
    <s0:Sale transactionnumber="2" register="1"> 
    <s0:Tender amount="5.55" paymentmethod="discover" /> 
    <s0:Tender amount="4.44" paymentmethod="visa" /> 
    </s0:Sale> 
    <s0:Sale transactionnumber="1" register="2"> 
    <s0:Tender amount="9.99" paymentmethod="amex" /> 
    <s0:Tender amount="8.88" paymentmethod="visa" /> 
    </s0:Sale> 
</s0:SalesCollection> 

產生想要的結果

<ns0:root xmlns:ns0="http://myDestinationSchema"> 
    <ns0:record type="detail" transactionnumber="1" register="1" amount="1.11" paymentmethod="visa"/> 
    <ns0:record type="detail" transactionnumber="1" register="1" amount="2.22" paymentmethod="mastercard"/> 
    <ns0:record type="detail" transactionnumber="2" register="1" amount="5.55" paymentmethod="discover"/> 
    <ns0:record type="detail" transactionnumber="2" register="1" amount="4.44" paymentmethod="visa"/> 
    <ns0:record type="detail" transactionnumber="1" register="2" amount="9.99" paymentmethod="amex"/> 
    <ns0:record type="detail" transactionnumber="1" register="2" amount="8.88" paymentmethod="visa"/> 
    <ns0:record type="summary" register="1" paymentmethod="visa" amount="5.55"/> 
    <ns0:record type="summary" register="1" paymentmethod="mastercard" amount="2.22"/> 
    <ns0:record type="summary" register="1" paymentmethod="discover" amount="5.55"/> 
    <ns0:record type="summary" register="2" paymentmethod="amex" amount="9.99"/> 
    <ns0:record type="summary" register="2" paymentmethod="visa" amount="8.88"/> 
</ns0:root> 

說明

正確使用方法:

  1. Muenchian Grouping method

  2. AVT s(屬性值模板)。

+1

複合分組密鑰的使用非常有幫助! – 2013-09-17 18:53:46

+0

@ J.Polfer,不客氣。 – 2013-09-17 22:36:20

1

當這個XSLT:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:ns0="http://myDestinationSchema" 
    xmlns:s0="http://mySourceSchema" 
    exclude-result-prefixes="s0" 
    version="1.0"> 
    <xsl:output omit-xml-declaration="yes" indent="yes"/> 
    <xsl:strip-space elements="*"/> 

    <xsl:key 
    name="kTenderByRegisterAndMethod" 
    match="s0:Tender" 
    use="concat(parent::*/@register, '+', @paymentmethod)"/> 

    <xsl:template match="@*|node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
    </xsl:template> 

    <xsl:template match="/*"> 
    <ns0:root> 
     <xsl:apply-templates select="*/s0:Tender"/> 
     <xsl:apply-templates 
     select="*/s0:Tender[generate-id() = 
          generate-id(key(
           'kTenderByRegisterAndMethod', 
           concat(parent::*/@register, 
            '+', 
            @paymentmethod))[1])]" 
     mode="summary"/> 
    </ns0:root> 
    </xsl:template> 

    <xsl:template match="s0:Tender"> 
    <ns0:record type="detail"> 
     <xsl:apply-templates select="parent::*/@*|@*"/> 
    </ns0:record> 
    </xsl:template> 

    <xsl:template match="s0:Tender" mode="summary"> 
    <ns0:record type="summary" register="{parent::*/@register}"> 
     <xsl:attribute name="amount"> 
     <xsl:value-of 
      select="sum(
        key('kTenderByRegisterAndMethod', 
         concat(parent::*/@register, 
         '+', @paymentmethod))/@amount)"/> 
     </xsl:attribute> 
     <xsl:apply-templates select="@*[not(name() = 'amount')]"/> 
    </ns0:record> 
    </xsl:template> 
</xsl:stylesheet> 

......被應用於原始XML:

<s0:SalesCollection xmlns:s0="http://mySourceSchema"> 
    <s0:Sale transactionnumber="1" register="1"> 
    <s0:Tender amount="1.11" paymentmethod="visa"/> 
    <s0:Tender amount="2.22" paymentmethod="mastercard"/> 
    </s0:Sale> 
    <s0:Sale transactionnumber="2" register="1"> 
    <s0:Tender amount="5.55" paymentmethod="discover"/> 
    <s0:Tender amount="4.44" paymentmethod="visa"/> 
    </s0:Sale> 
    <s0:Sale transactionnumber="1" register="2"> 
    <s0:Tender amount="9.99" paymentmethod="amex"/> 
    <s0:Tender amount="8.88" paymentmethod="visa"/> 
    </s0:Sale> 
</s0:SalesCollection> 

......想要的結果產生:

<ns0:root xmlns:ns0="http://myDestinationSchema"> 
    <ns0:record type="detail" transactionnumber="1" register="1" amount="1.11" paymentmethod="visa"/> 
    <ns0:record type="detail" transactionnumber="1" register="1" amount="2.22" paymentmethod="mastercard"/> 
    <ns0:record type="detail" transactionnumber="2" register="1" amount="5.55" paymentmethod="discover"/> 
    <ns0:record type="detail" transactionnumber="2" register="1" amount="4.44" paymentmethod="visa"/> 
    <ns0:record type="detail" transactionnumber="1" register="2" amount="9.99" paymentmethod="amex"/> 
    <ns0:record type="detail" transactionnumber="1" register="2" amount="8.88" paymentmethod="visa"/> 
    <ns0:record type="summary" register="1" amount="5.55" paymentmethod="visa"/> 
    <ns0:record type="summary" register="1" amount="2.22" paymentmethod="mastercard"/> 
    <ns0:record type="summary" register="1" amount="5.55" paymentmethod="discover"/> 
    <ns0:record type="summary" register="2" amount="9.99" paymentmethod="amex"/> 
    <ns0:record type="summary" register="2" amount="8.88" paymentmethod="visa"/> 
</ns0:root> 

說明

您是在正確的軌道上檢查Muenchian分組。請注意,我使用的組合鍵與s0:Tender元素匹配,它們通過連接其父項的@register值,「+」號(爲了方便起見而存在以確保級聯不會發生重疊)和它們的@paymentmethod值。

堅持Muenchian分組,即使它不是最簡單的概念瞭解蝙蝠。我,我自己,通過查看Muenchian Grouping-related questions on SO並試圖回答他們;隨着時間的推移,它開始爲我清理。