XSL:xsl:if 测试不工作并计算总和
XSL: xsl:if test not working and calculate sum
对于下面的简化转换sheet,我想添加以下功能:
- 对于“2019 年营业额”和“2020 年营业额”,我希望红色徽章中的值低于 1mio,绿色徽章中的值超过 1mio。我试图为“2019 年营业额”实施此操作,但我只得到一个空白输出。问题似乎出在
<xsl:if test="...">
部分,因为如果我只输入 <xsl:value-of select="key('keyToCreditcard', id)/turnover_2019"/>
(请参阅“2020 年营业额”),我确实得到了正确的值。
- 对于“总营业额”,我需要总结“2019 年营业额”和“2020 年营业额”的值。我该怎么做?
XSL:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="keyToPerson" match="person" use="id"/>
<xsl:key name="keyToCreditcard" match="creditcard" use="cardowner"/>
<xsl:template match="/">
<xsl:for-each select="data/persons/person">
<xsl:if test="turnoverYear1 < 1000000">
<span class="badge bg-warning mx-2"><xsl:value-of select="key('keyToCreditcard', id)/turnoverYear1"/></span>
</xsl:if>
<xsl:if test="turnoverYear1 > 999999.99">
<span class="badge bg-danger mx-2"><xsl:value-of select="key('keyToCreditcard', id)/turnoverYear1"/></span>
</xsl:if>
<xsl:value-of select="key('keyToCreditcard', id)/turnoverYear2"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
输入:
<data>
<persons>
<person>
<id>1</id>
<name>Jeramie Bischoff</name>
<city>Luzern</city>
<birthdate>04/16/1951</birthdate>
</person>
</persons>
<creditcards>
<creditcard>
<id>1</id>
<cardtype>Visa</cardtype>
<cardnumber>4041592612048990</cardnumber>
<turnoverYear1>952411.33</turnoverYear1>
<turnoverYear2>6135840.0</turnoverYear2>
<cardowner>1</cardowner>
</creditcard>
</creditcards>
</data>
预期输出:
Name:Jeramie Bischoff
City: Luzern
birthdate: 04/16/1951
Card Type: Visa
Card Number: 4041592612048990
Turnover 2019: 952411.33
Turnover 2020: 6135840.0
Total Turnover: 7088251.33
根据您的示例 XML,一个好的方法是将内容拆分为多个模板。
一个处理创建基本 HTML 文档结构 (match="/"
),一个处理 <person>
元素,一个处理营业额徽章,等等。一般来说,<xsl:apply-templates>
比使用一堆嵌套的 <xsl:for-each>
.
将所有内容塞进一个模板中更有好处。
由于您有一个将个人 ID 链接到信用卡的 <xsl:key>
,因此可以使用它来将 <creditcard>
提取到变量 ($cc
) 中并使用它。
<xsl:output method="html" indent="yes" />
<xsl:key name="keyToCreditcard" match="creditcard" use="cardowner"/>
<xsl:template match="/">
<html>
<!-- ... -->
<xsl:apply-templates select="data/persons/person" />
<!-- ... -->
</html>
</xsl:template>
<xsl:template match="person">
<div class="person">
<xsl:variable name="cc" select="key('keyToCreditcard', id)" />
<!-- your question #1 -->
<div>
<xsl:text>Turnover 2019: </xsl:text>
<xsl:apply-templates select="$cc/turnoverYear1" />
</div>
<div>
<xsl:text>Turnover 2020: </xsl:text>
<xsl:apply-templates select="$cc/turnoverYear2" />
</div>
<!-- your question #2 -->
<div>
<xsl:text>Total Turnover: </xsl:text>
<xsl:value-of select="$cc/turnoverYear1 + $cc/turnoverYear2" />
</div>
</div>
</xsl:template>
<xsl:template match="turnoverYear1|turnoverYear2">
<span>
<xsl:attribute name="class">
<xsl:text>badge mx-2 </xsl:text>
<xsl:choose>
<xsl:when test=". < 1000000">bg-warning</xsl:when>
<xsl:when test=". < 99999.99">bg-danger</xsl:when>
</xsl:choose>
</xsl:attribute>
<xsl:value-of select="." />
</span>
</xsl:template>
这导致
<html>
<div class="person">
<div>Turnover 2019: <span class="badge mx-2 bg-warning">952411.33</span></div>
<div>Turnover 2020: <span class="badge mx-2">6135840.0</span></div>
<div>Total Turnover: 7088251.33</div>
</div>
</html>
因为年份数字和 XML 元素名称在您的 XML 中是一个移动目标,所以您每年都必须不断调整 XSLT 代码。那是完全没有必要的。将年份排除在 XML 元素名称之外要聪明得多。将其移动到属性中:
<creditcards>
<creditcard>
<id>1</id>
<cardtype>Visa</cardtype>
<cardnumber>4041592612048990</cardnumber>
<turnover year="2019">952411.33</turnover>
<turnover year="2020">6135840.0</turnover>
<cardowner>1</cardowner>
</creditcard>
</creditcards>
使用这样的 <creditcard>
设置,XSLT 代码变得更加通用。
<xsl:template match="person">
<div class="person">
<xsl:variable name="cc" select="key('keyToCreditcard', id)" />
<!-- your question #1 -->
<xsl:apply-templates select="$cc/turnover" />
<!-- your question #2 -->
<div>
<xsl:text>Total Turnover: </xsl:text>
<xsl:value-of select="sum($cc/turnover)" />
</div>
</div>
</xsl:template>
<xsl:template match="turnover">
<div>
<xsl:value-of select="concat('Turnover ', @year, ': ')" />
<span>
<xsl:attribute name="class">
<xsl:text>badge mx-2 </xsl:text>
<xsl:choose>
<xsl:when test=". < 1000000">bg-warning</xsl:when>
<xsl:when test=". < 99999.99">bg-danger</xsl:when>
</xsl:choose>
</xsl:attribute>
<xsl:value-of select="." />
</span>
</div>
</xsl:template>
对于下面的简化转换sheet,我想添加以下功能:
- 对于“2019 年营业额”和“2020 年营业额”,我希望红色徽章中的值低于 1mio,绿色徽章中的值超过 1mio。我试图为“2019 年营业额”实施此操作,但我只得到一个空白输出。问题似乎出在
<xsl:if test="...">
部分,因为如果我只输入<xsl:value-of select="key('keyToCreditcard', id)/turnover_2019"/>
(请参阅“2020 年营业额”),我确实得到了正确的值。 - 对于“总营业额”,我需要总结“2019 年营业额”和“2020 年营业额”的值。我该怎么做?
XSL:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="keyToPerson" match="person" use="id"/>
<xsl:key name="keyToCreditcard" match="creditcard" use="cardowner"/>
<xsl:template match="/">
<xsl:for-each select="data/persons/person">
<xsl:if test="turnoverYear1 < 1000000">
<span class="badge bg-warning mx-2"><xsl:value-of select="key('keyToCreditcard', id)/turnoverYear1"/></span>
</xsl:if>
<xsl:if test="turnoverYear1 > 999999.99">
<span class="badge bg-danger mx-2"><xsl:value-of select="key('keyToCreditcard', id)/turnoverYear1"/></span>
</xsl:if>
<xsl:value-of select="key('keyToCreditcard', id)/turnoverYear2"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
输入:
<data>
<persons>
<person>
<id>1</id>
<name>Jeramie Bischoff</name>
<city>Luzern</city>
<birthdate>04/16/1951</birthdate>
</person>
</persons>
<creditcards>
<creditcard>
<id>1</id>
<cardtype>Visa</cardtype>
<cardnumber>4041592612048990</cardnumber>
<turnoverYear1>952411.33</turnoverYear1>
<turnoverYear2>6135840.0</turnoverYear2>
<cardowner>1</cardowner>
</creditcard>
</creditcards>
</data>
预期输出:
Name:Jeramie Bischoff
City: Luzern
birthdate: 04/16/1951
Card Type: Visa
Card Number: 4041592612048990
Turnover 2019: 952411.33
Turnover 2020: 6135840.0
Total Turnover: 7088251.33
根据您的示例 XML,一个好的方法是将内容拆分为多个模板。
一个处理创建基本 HTML 文档结构 (match="/"
),一个处理 <person>
元素,一个处理营业额徽章,等等。一般来说,<xsl:apply-templates>
比使用一堆嵌套的 <xsl:for-each>
.
由于您有一个将个人 ID 链接到信用卡的 <xsl:key>
,因此可以使用它来将 <creditcard>
提取到变量 ($cc
) 中并使用它。
<xsl:output method="html" indent="yes" />
<xsl:key name="keyToCreditcard" match="creditcard" use="cardowner"/>
<xsl:template match="/">
<html>
<!-- ... -->
<xsl:apply-templates select="data/persons/person" />
<!-- ... -->
</html>
</xsl:template>
<xsl:template match="person">
<div class="person">
<xsl:variable name="cc" select="key('keyToCreditcard', id)" />
<!-- your question #1 -->
<div>
<xsl:text>Turnover 2019: </xsl:text>
<xsl:apply-templates select="$cc/turnoverYear1" />
</div>
<div>
<xsl:text>Turnover 2020: </xsl:text>
<xsl:apply-templates select="$cc/turnoverYear2" />
</div>
<!-- your question #2 -->
<div>
<xsl:text>Total Turnover: </xsl:text>
<xsl:value-of select="$cc/turnoverYear1 + $cc/turnoverYear2" />
</div>
</div>
</xsl:template>
<xsl:template match="turnoverYear1|turnoverYear2">
<span>
<xsl:attribute name="class">
<xsl:text>badge mx-2 </xsl:text>
<xsl:choose>
<xsl:when test=". < 1000000">bg-warning</xsl:when>
<xsl:when test=". < 99999.99">bg-danger</xsl:when>
</xsl:choose>
</xsl:attribute>
<xsl:value-of select="." />
</span>
</xsl:template>
这导致
<html>
<div class="person">
<div>Turnover 2019: <span class="badge mx-2 bg-warning">952411.33</span></div>
<div>Turnover 2020: <span class="badge mx-2">6135840.0</span></div>
<div>Total Turnover: 7088251.33</div>
</div>
</html>
因为年份数字和 XML 元素名称在您的 XML 中是一个移动目标,所以您每年都必须不断调整 XSLT 代码。那是完全没有必要的。将年份排除在 XML 元素名称之外要聪明得多。将其移动到属性中:
<creditcards>
<creditcard>
<id>1</id>
<cardtype>Visa</cardtype>
<cardnumber>4041592612048990</cardnumber>
<turnover year="2019">952411.33</turnover>
<turnover year="2020">6135840.0</turnover>
<cardowner>1</cardowner>
</creditcard>
</creditcards>
使用这样的 <creditcard>
设置,XSLT 代码变得更加通用。
<xsl:template match="person">
<div class="person">
<xsl:variable name="cc" select="key('keyToCreditcard', id)" />
<!-- your question #1 -->
<xsl:apply-templates select="$cc/turnover" />
<!-- your question #2 -->
<div>
<xsl:text>Total Turnover: </xsl:text>
<xsl:value-of select="sum($cc/turnover)" />
</div>
</div>
</xsl:template>
<xsl:template match="turnover">
<div>
<xsl:value-of select="concat('Turnover ', @year, ': ')" />
<span>
<xsl:attribute name="class">
<xsl:text>badge mx-2 </xsl:text>
<xsl:choose>
<xsl:when test=". < 1000000">bg-warning</xsl:when>
<xsl:when test=". < 99999.99">bg-danger</xsl:when>
</xsl:choose>
</xsl:attribute>
<xsl:value-of select="." />
</span>
</div>
</xsl:template>