2017-06-20 64 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>