【问题标题】:XSL comparing two element values and changing itXSL 比较两个元素值并更改它
【发布时间】:2014-10-02 22:43:43
【问题描述】:

我正在尝试对通过 XSL 获得的 xml 文件进行一些小的修改。 XSL 不是我真正的东西,但我设法进行了一些先前的修改,但我坚持比较不同元素的两个值,然后根据条件进行更改。条件是,如果 value1 小于 value2,则将 value2 加 10。下面是.xml

    <Parent1>
        <Parent2>
            <VALUE1>10:30</VALUE1>
            <VALUE2>15:30</VALUE2>
            <VALUE3>13:00</VALUE3>
            <VALUE4>13:30</VALUE4>
            <VALUE5>13:30</VALUE5>
            <VALUE6>13:00</VALUE6>
            <VALUE7>13:30</VALUE7>
            <VALUE8>13:00</VALUE8>
            <VALUE9>13:00</VALUE9>
            <VALUE10>13:00</VALUE10>
            <CHECK1>12</CHECK1>
            <CHECK2>18</CHECK2>
            <CHECK3>2</CHECK3>
            <FINAL></FINAL>
        </Parent2>
    </Parent1>

我在想类似的东西

        <xsl:template match="*"> 
                    <xsl:copy> 
                            <xsl:apply-templates select="@*|node()"/> 
                    </xsl:copy> 
        </xsl:template> 

    <xsl:template match="/">    
                           <xsl:for-each select="Parent2">
                            <xsl:if test="VALUE1 < VALUE2">
                           <!---- add 10 to VALUE2   ------>

    </xsl:template>  
</xsl:stylesheet>

任何人都可以帮助我或指出正确的方向,正如我所说的,我并没有真正使用 XSL。提前谢谢你

【问题讨论】:

    标签: xml xslt


    【解决方案1】:

    条件是,如果 value1 小于 value2 则将 value2 加 10。

    这意味着您只想更改 value2 - 因此最好有一个匹配 value2 的专用模板(除了通用 identity transform 模板以复制所有其他节点而不进行修改):

    <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="*"/>
    
    <!-- identity transform -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    
    <xsl:template match="VALUE2">
        <xsl:copy>
            <xsl:choose>
                <xsl:when test="../VALUE1 &lt; .">
                    <xsl:value-of select=". + 10"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="."/>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:copy>
    </xsl:template>
    
    </xsl:stylesheet>
    

    或者只是:

    <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="*"/>
    
    <!-- identity transform -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    
    <xsl:template match="VALUE2[. > ../VALUE1] ">
        <xsl:copy>
            <xsl:value-of select=". + 10"/>
        </xsl:copy>
    </xsl:template>
    
    </xsl:stylesheet>
    

    编辑:

    回复您编辑的问题:

    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="*"/>
    
    <!-- identity transform -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    
    <xsl:template match="VALUE2">
        <xsl:copy>
            <xsl:variable name="time" select="60*substring-before(., ':') + substring-after(., ':')" />
            <xsl:variable name="val1" select="../VALUE1" />
            <xsl:variable name="time1" select="60*substring-before($val1, ':') + substring-after($val1, ':')" />
            <xsl:choose>
                <xsl:when test="$time1 &lt; $time">
                    <xsl:value-of select="10 + floor($time div 60) "/>
                    <xsl:value-of select="format-number($time mod 60, ':00') "/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="."/>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:copy>
    </xsl:template>
    
    </xsl:stylesheet>
    

    【讨论】:

    • 感谢一百万,如果我也可以寻求一点帮助,如果这些值实际上是时间/小时格式(即 12:30、08:30),我想使用值上的子字符串并比较小时数,但我不知道该怎么说:(
    • @user2842773 恐怕我不关注。您为什么不编辑您的问题,添加一个新示例并阐明条件和预期结果是什么。 -- 还要说明您使用的是 XSLT 1.0 还是 2.0。
    • ok,所以如果元素下的值是这样的,那么它基本上是以小时为单位的时间值,但它也可以看起来像60:30,所以在value1小于value2的情况下我需要将 10 添加到 value2。 (即 value1=10:00, value2=15:30 新的 value2 应该是 25:30)
    • @user2842773 你的意思是把时间加 10 小时 吗? -- 另外请说明您使用的是哪个版本的 XSLT。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-11-23
    • 1970-01-01
    • 2022-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多