我有一个这样的xml表:
<houses>
<house number="1">
<mainroom>
<roomprice>5</roomprice>
<roomtax>2</roomtax>
</mainroom>
<roompricefull>
<price value="8"/>
</roompricefull>
</house>
<house number="2">
<mainroom>
<roomprice>3</roomprice>
<roomtax>1</roomtax>
</mainroom>
<roompricefull>
<price value="7"/>
</roompricefull>
</house>
<house number="3">
<mainroom>
<roomprice>9</roomprice>
<roomtax>1</roomtax>
</mainroom>
<roompricefull>
<price value="4"/>
</roompricefull>
</house>
<house number="4">
<mainroom>
<roomprice>12</roomprice>
<roomtax>3</roomtax>
</mainroom>
<roompricefull>
<price value="6"/>
</roompricefull>
</house>
</houses>
所以我不得不用"房间价格"值和"房间税"的总和来改变每个"房子"中"价格"元素中属性"价值"的值
我写了一个xsl转换:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template name="PriceChange" match="price[parent::roompricefull]">
<xsl:copy>
<xsl:variable name="sn" select="../../@number"/>
<xsl:variable name="TaxValue" select="number(//house[@number=string($sn)]/mainroom/roomtax)"/>
<xsl:variable name="BaseValue" select="number(//house[@number=string($sn)]/mainroom/roomprice)"/>
<xsl:attribute name="value">
<xsl:value-of select="string($TaxValue+$BaseValue)"/>
</xsl:attribute>
<!--xsl:for-each select="/houses/house">
<xsl:sort select="houses/house[$sn]/roompricefull/@value"/>
</xsl:for-each-->
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
但当我开始根据我的新价值对"房子"元素进行排序时,我发现了问题。实际上,我不明白为什么它不起作用,所以我在up代码中评论了几十个例子中的最后一个。
我得到了这个:
<houses>
<house number="1">
<mainroom>
<roomprice>5</roomprice>
<roomtax>2</roomtax>
</mainroom>
<roompricefull>
<price value="7"/>
</roompricefull>
</house>
<house number="2">
<mainroom>
<roomprice>3</roomprice>
<roomtax>1</roomtax>
</mainroom>
<roompricefull>
<price value="4"/>
</roompricefull>
</house>
<house number="3">
<mainroom>
<roomprice>9</roomprice>
<roomtax>1</roomtax>
</mainroom>
<roompricefull>
<price value="10"/>
</roompricefull>
</house>
<house number="4">
<mainroom>
<roomprice>12</roomprice>
<roomtax>3</roomtax>
</mainroom>
<roompricefull>
<price value="15"/>
</roompricefull>
</house>
</houses>
但预期的结果是:
<houses>
<house number="4">
<mainroom>
<roomprice>12</roomprice>
<roomtax>3</roomtax>
</mainroom>
<roompricefull>
<price value="15"/>
</roompricefull>
</house>
<house number="3">
<mainroom>
<roomprice>9</roomprice>
<roomtax>1</roomtax>
</mainroom>
<roompricefull>
<price value="10"/>
</roompricefull>
</house>
<house number="1">
<mainroom>
<roomprice>5</roomprice>
<roomtax>2</roomtax>
</mainroom>
<roompricefull>
<price value="7"/>
</roompricefull>
</house>
<house number="2">
<mainroom>
<roomprice>3</roomprice>
<roomtax>1</roomtax>
</mainroom>
<roompricefull>
<price value="4"/>
</roompricefull>
</house>
</houses>
如果你能帮我整理和解释为什么我的例子不起作用,那就太好了。似乎我不明白<sort/>,但我找到的所有东西告诉我它的用法,没有任何解释。提前谢谢。
如果你能帮我分拣就太好了
这是正确的XSLT1.0方法。
注意xsl:sort
的正确使用,它需要:
- 要指定的数据类型,默认为string,而我们在这里需要数字
xsl:apply-templates
内部排序的最佳使用- 根据需要组合输入文档的排序键进行排序的应用(sum)
-
也要指定的排序顺序是默认的
ascending
<xsl:output indent="yes"/> <xsl:strip-space elements="*"/> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <xsl:template match="houses"> <xsl:copy> <xsl:apply-templates select="house"> <xsl:sort select="mainroom/roomprice + mainroom/roomtax" data-type="number" order="descending"/> </xsl:apply-templates> </xsl:copy> </xsl:template> <xsl:template match="price/@value"> <xsl:value-of select=" ../../../mainroom/roomprice + ../../../mainroom/roomtax"/> </xsl:template>
解释为什么我的示例不起作用
您的转换不起作用,主要是因为您试图对错误上下文中的元素进行排序(在与树中的深层子项匹配的模板内)。此外:
- 您正试图通过绝对XPath模式对指示排序键的排序进行排序
- 您没有指定所需的
xsl:sort
属性 - 您希望最终元素根据之后计算的值进行排序,并且不出现在输入文档中。这不是正确的做法。您必须始终使用输入文档中存在的值,最终正确组合它们
按新价格排序:
<xsl:template match="/">
<xsl:for-each select="house">
<xsl:sort select="mainroom/roomprice + mainroom/roomtax"/>
<xsl:apply-templates select="."/>
</xsl:for-each>
</xsl:template>
如前所述:
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
调整输出中的价格:
<xsl:template match="roompricefull">
<roompricefull>
<price value="{../mainroom/roomprice + ../mainroom/roomtax}"/>
</roompricefull>
</xsl:template>