如何根据元素子元素中的新计数值对元素进行排序.XSLT 1.0



我有一个这样的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>

相关内容

  • 没有找到相关文章

最新更新