如何按子元素中的新计数值对元素进行排序.XSLT 1.0 [英] How can I sort elements by new counted values in their child element. XSLT 1.0

查看:34
本文介绍了如何按子元素中的新计数值对元素进行排序.XSLT 1.0的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个这种类型的 xml 表:

I have an xml sheet of this kind:

<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>

所以我不得不用roomprice"值和roomtax"的总和来改变每个house"中price"元素中属性value"的值

so I had to change the value of attribute "value" in "price" element in each of the "house" with the sum of "roomprice" value and "roomtax"

我写了一个这样的 xsl 转换:

I wrote an xsl transformation of such a kind:

<?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 代码中评论了我的最后一个例子.

But when I started working on sorting "house" elements by my new value, I found problems. I actually don't understand why it's not working, so I commented my last of the dozens examples in up code.

我明白了:

<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/> 的含义,但我找到的一切都告诉我它的用法,没有任何解释.提前致谢.

It would be great if you could help me with sorting and explaining why my example is not working. Seems that I don't understand the meaning of <sort/>, but everything I find tells me just about the usage of it without any explanation. Thank you in advance.

推荐答案

如果你能帮我排序就好了

这是正确的 XSLT 1.0 方法.

This is the correct XSLT 1.0 approach.

注意 xsl:sort 的正确使用,它需要:

Notice the correct use of xsl:sort which needs:

  • 要指定的数据类型,默认为字符串,而我们在这里需要数字
  • 最好使用 xsl:apply-templates
  • 将输入文档的排序键按要求组合(求和)进行排序的应用.
  • 也要指定的排序顺序是默认的升序

<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>

解释为什么我的例子不起作用

您的转换不起作用主要是因为您试图在错误的上下文中对元素进行排序(在匹配树中深子级的模板内).此外:

Your transform does no work mainly because you are trying to sort elements in the wrong context (inside a template matching a deep child in the tree). Moreover:

  • 您正在尝试按绝对 XPath 模式对指示排序键进行排序.
  • 您没有指定所需的 xsl:sort 属性
  • 您希望最终元素根据之后计算的值进行排序,而不是出现在输入文档中.这不是正确的方法.您必须始终使用输入文档中存在的值,最终将它们正确组合.

这篇关于如何按子元素中的新计数值对元素进行排序.XSLT 1.0的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆