但我还有其他问题,每个事件减去值B和P.源代码例如如下:
<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 :(得分: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>
答案 1 :(得分:0)
另一种方法是使用分组:
XSLT 2.0
{{1}}
答案 2 :(得分: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>