2017-06-20 63 views
0

但是對於每個事件,我還有其他問題,即減去值B和P.源代碼,例如這樣的:在xslt 1.0中用排序節點減去

<EVENTS> 
<ROW ID="204" ID_PLACE="1" EVENT_TYPE="B" EVENT_NAME="TEST1" EVENT_ID="201"> 
<PRICE> 
<ROW EVENT_PRICE="165,00"/> 
</PRICE> 
</ROW> 
<ROW ID="205" ID_PLACE="1" EVENT_TYPE="P" EVENT_NAME="TEST1" EVENT_ID="201"> 
<PRICE> 
<ROW EVENT_PRICE="125,00"/> 
</PRICE> 
</ROW> 
<ROW ID="206" ID_PLACE="1" EVENT_TYPE="B" EVENT_NAME="TEST2" EVENT_ID="202"> 
<PRICE> 
<ROW EVENT_PRICE="100,00"/> 
</PRICE> 
</ROW> 
<ROW ID="207" ID_PLACE="1" EVENT_TYPE="P" EVENT_NAME="TEST2" EVENT_ID="202"> 
<PRICE> 
<ROW EVENT_PRICE="135,00"/> 
</PRICE> 
</ROW> 
</EVENTS> 

,我必須得到類似的東西:

<EVENT_ID>201</EVENT_ID> 
<DIFF>40.00</DIFF> 
<EVENT_ID>202</EVENT_ID> 
<DIFF>-35.00</DIFF> 

等。在這種情況下,我現在什麼EVENT_ID是在文件中,但並不總是它是唯一這兩個ID,所以我不能這樣做:對於ID = 201 diff是40,對於202 diff是-35。如何爲源代碼中的每個ID_EVENT編寫xsl轉換。

+0

對於每個EVENT_ID總會有一個「B」和「P」行?謝謝 –

+0

對於上下文來說,參考[你以前的問題](https://stackoverflow.com/questions/44640215/subtract-in-xslt-1-0/44641119#44641119)本來是很好的。 –

+0

您在標題中提及「排序節點」,但不清楚如何進行排序。我所看到的確實是,你*通過它們的'EVENT_ID'屬性匹配*''元素,這是非常不同的事情。你是否在尋找分類輸出?如果是這樣,那麼按什麼鍵? '@ EVENT_ID'? –

回答

0

我會用一個key由他們EVENT_ID行鏈接:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:key name="p" match="ROW[@EVENT_TYPE='P']" use="@EVENT_ID" /> 

<xsl:template match="/EVENTS"> 
    <EVENTS> 
     <xsl:for-each select="ROW[@EVENT_TYPE='B']"> 
      <xsl:variable name="B" select="PRICE/ROW/@EVENT_PRICE"/> 
      <xsl:variable name="P" select="key('p', @EVENT_ID)/PRICE/ROW/@EVENT_PRICE"/> 
      <xsl:variable name="diff" select="translate($B, ',', '.') - translate($P, ',', '.')" /> 
      <EVENT_ID> 
       <xsl:value-of select="@EVENT_ID" /> 
      </EVENT_ID> 
      <DIFF> 
       <xsl:value-of select="format-number($diff, '0.00')" /> 
      </DIFF> 
     </xsl:for-each> 
    </EVENTS> 
</xsl:template> 

</xsl:stylesheet> 

演示:http://xsltransform.net/bEzjRJW

0

另一種方法是使用分組:

XSLT 2.0

<xsl:for-each-group select="EVENTS/ROW" group-by="EVENT_ID"> 
    <xsl:variable name="B" select="current-group()[EVENT_TYPE='B']/PRICE/ROW/@EVENT_PRICE"/> 
    <xsl:variable name="P" select="current-group()[EVENT_TYPE='P']/PRICE/ROW/@EVENT_PRICE"/>    
    <xsl:variable name="diff" select="translate($B, ',', '.') - translate($P, ',', '.')" /> 
    <EVENT_ID> 
    <xsl:value-of select="current-grouping-key()" /> 
    </EVENT_ID> 
    <DIFF> 
    <xsl:value-of select="format-number($diff, '0.00')" /> 
    </DIFF> 
</xsl:for-each-group> 
0

my answer to your previous question,我指出,還有其他的方法可以解決匹配對應<ROW>元素比尋找那些具有共同<EVENTS>父的問題。在這個問題中提出的情況需要這種方法。

正如其他答案所暗示的,人們可以通過鍵或XSLT 2.0分組來實現這一點。但另一種方法是簡單地編寫一個合適的XPath表達式來選擇匹配每個'B'行的'P'行(或反之亦然)。例如,

<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:strip-space elements="*"/> 
    <xsl:decimal-format decimal-separator="." zero-digit="0" minus-sign="-" /> 

    <!-- transform based on 'B' rows --> 
    <xsl:template match="EVENTS/ROW[@EVENT_TYPE = 'B']"> 
    <xsl:variable name="event-id" select="@EVENT_ID"/> 
    <!-- select the corresponding 'P' row, if any --> 
    <xsl:variable name="event-p" select="../ROW[@EVENT_TYPE = 'P' and @EVENT_ID = $event-id]"/> 
    <!-- supposing that there was a matching 'P' row ... --> 
    <xsl:if test="$event-p"> 
     <!-- extract the two rows' prices here to simplify later expressions --> 
     <xsl:variable name="b-price" 
      select="number(translate(PRICE/ROW/@EVENT_PRICE, ',', '.'))"/> 
     <xsl:variable name="p-price" 
      select="number(translate($event-p/PRICE/ROW/@EVENT_PRICE, ',', '.'))"/> 
     <!-- Add the wanted elements to the result tree --> 
     <EVENT_ID> 
     <xsl:value-of select="$event-id"/> 
     </EVENT_ID> 
     <DIFF> 
     <!-- If you require the specific numeric format you presented, then 
      you need to ask for it --> 
     <xsl:value-of select="format-number($b-price - $p-price, '0.00;-0.00')" /> 
     </DIFF> 
    </xsl:if> 
    </xsl:template> 

</xsl:stylesheet>