添加上一节点值和数字

时间:2012-08-15 09:14:56

标签: xml xslt add

我正在尝试将1添加到节点的上一次出现。它背后的逻辑是,如果之前的节点在指定的三个字段上不匹配;然后将位置设置为1。如果前一个节点与前一个节点匹配,则从前一个位置获取值并添加1

我已创建XSLT来完成此操作,但我不知道如何将1添加到上一个节点。

当我使用代码片段时:

<xsl:value-of select="preceding-sibling::orderLine/position + '1'"/>

我在输出中得到的回应是:

<position>NaN</position>

我正在使用的XSLT是:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:strip-space elements="*"/>
    <xsl:output indent="yes"/>

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

    <xsl:template
        match="/order/orderLines/orderLine[sku = preceding-sibling::orderLine/sku and lineId = preceding-sibling::orderLine/lineId]"/>

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


                <xsl:choose>

                    <xsl:when
                        test="lineId = preceding-sibling::orderLine/lineId and sku = preceding-sibling::orderLine/sku and lineTrackingUrl = preceding-sibling::orderLine/lineTrackingUrl">
                        <position>
                            <!-- THE ISSUE IS HERE -->
                            <xsl:value-of select="preceding-sibling::orderLine/position + '1'"/>
                            <!-- THE ISSUE IS HERE -->
                        </position>
                    </xsl:when>
                    <xsl:otherwise>
                        <position>1</position>
                    </xsl:otherwise>
                </xsl:choose>

            </xsl:copy>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

示例输入:

    <?xml version="1.0" encoding="utf-8"?>
<order>
    <orderLines>
        <orderLine>
            <lineId>4</lineId>
            <sku>1111111</sku>
            <lineTrackingUrl>![CDATA[1111111111]]</lineTrackingUrl>
        </orderLine>
        <orderLine>
            <lineId>4</lineId>
            <sku>1111111</sku>
            <lineTrackingUrl>![CDATA[1111111111]]</lineTrackingUrl>
        </orderLine>
        <orderLine>
            <lineId>4</lineId>
            <sku>1111111</sku>
            <lineTrackingUrl>![CDATA[1111111111]]</lineTrackingUrl>
        </orderLine>
        <orderLine>
            <lineId>4</lineId>
            <sku>1111111</sku>
            <lineTrackingUrl>![CDATA[1111111111]]</lineTrackingUrl>
        </orderLine>
        <orderLine>
            <lineId>3</lineId>
            <sku>1111111</sku>
            <lineTrackingUrl>![CDATA[1111111111]]</lineTrackingUrl>
        </orderLine>
        <orderLine>
            <lineId>3</lineId>
            <sku>1111111</sku>
            <lineTrackingUrl>![CDATA[1111111111]]</lineTrackingUrl>
        </orderLine>
        <orderLine>
            <lineId>3</lineId>
            <sku>1111111</sku>
            <lineTrackingUrl>![CDATA[1111111111]]</lineTrackingUrl>
        </orderLine>
        <orderLine>
            <lineId>3</lineId>
            <sku>1111111</sku>
            <lineTrackingUrl>![CDATA[1111111111]]</lineTrackingUrl>
        </orderLine>
    </orderLines>
</order>

如果你使用上面的示例输入,它完全说明了为什么这不起作用:

预期结果:

<?xml version="1.0" encoding="utf-8"?>
<order>
    <orderLine>
        <lineId>4</lineId>
        <sku>1111111</sku>
        <lineTrackingUrl>![CDATA[1111111111]]</lineTrackingUrl>
        <position>0</position>
    </orderLine>
    <orderLine>
        <lineId>4</lineId>
        <sku>1111111</sku>
        <lineTrackingUrl>![CDATA[1111111111]]</lineTrackingUrl>
        <position>1</position>
    </orderLine>
    <orderLine>
        <lineId>4</lineId>
        <sku>1111111</sku>
        <lineTrackingUrl>![CDATA[1111111111]]</lineTrackingUrl>
        <position>2</position>
    </orderLine>
    <orderLine>
        <lineId>4</lineId>
        <sku>1111111</sku>
        <lineTrackingUrl>![CDATA[1111111111]]</lineTrackingUrl>
        <position>3</position>
    </orderLine>
    <orderLine>
        <lineId>3</lineId>
        <sku>1111111</sku>
        <lineTrackingUrl>![CDATA[1111111111]]</lineTrackingUrl>
        <position>0</position>
    </orderLine>
    <orderLine>
        <lineId>3</lineId>
        <sku>1111111</sku>
        <lineTrackingUrl>![CDATA[1111111111]]</lineTrackingUrl>
        <position>1</position>
    </orderLine>
    <orderLine>
        <lineId>3</lineId>
        <sku>1111111</sku>
        <lineTrackingUrl>![CDATA[1111111111]]</lineTrackingUrl>
        <position>2</position>
    </orderLine>
    <orderLine>
        <lineId>3</lineId>
        <sku>1111111</sku>
        <lineTrackingUrl>![CDATA[1111111111]]</lineTrackingUrl>
        <position>3</position>
    </orderLine>
</order>

实际结果:

<?xml version="1.0" encoding="utf-8"?>
<order>
    <orderLine>
        <lineId>4</lineId>
        <sku>1111111</sku>
        <lineTrackingUrl>![CDATA[1111111111]]</lineTrackingUrl>
        <position>0</position>
    </orderLine>
    <orderLine>
        <lineId>4</lineId>
        <sku>1111111</sku>
        <lineTrackingUrl>![CDATA[1111111111]]</lineTrackingUrl>
        <position>1</position>
    </orderLine>
    <orderLine>
        <lineId>4</lineId>
        <sku>1111111</sku>
        <lineTrackingUrl>![CDATA[1111111111]]</lineTrackingUrl>
        <position>2</position>
    </orderLine>
    <orderLine>
        <lineId>4</lineId>
        <sku>1111111</sku>
        <lineTrackingUrl>![CDATA[1111111111]]</lineTrackingUrl>
        <position>3</position>
    </orderLine>
    <orderLine>
        <lineId>3</lineId>
        <sku>1111111</sku>
        <lineTrackingUrl>![CDATA[1111111111]]</lineTrackingUrl>
        <position>0</position>
    </orderLine>
    <orderLine>
        <lineId>3</lineId>
        <sku>1111111</sku>
        <lineTrackingUrl>![CDATA[1111111111]]</lineTrackingUrl>
        <position>5</position>
    </orderLine>
    <orderLine>
        <lineId>3</lineId>
        <sku>1111111</sku>
        <lineTrackingUrl>![CDATA[1111111111]]</lineTrackingUrl>
        <position>6</position>
    </orderLine>
    <orderLine>
        <lineId>3</lineId>
        <sku>1111111</sku>
        <lineTrackingUrl>![CDATA[1111111111]]</lineTrackingUrl>
        <position>7</position>
    </orderLine>
</order>

这不起作用的原因是因为它可以与之前的节点匹配:

这是代码:

<xsl:when
    test="lineId = preceding-sibling::orderLine/lineId and sku = preceding-sibling::orderLine/sku and lineTrackingUrl = preceding-sibling::orderLine/lineTrackingUrl">
    <position>
        <xsl:value-of select="count(preceding-sibling::orderLine/lineId)"/>
    </position>
</xsl:when>

您会看到时间的testlineId = preceding-sibling::orderLine/lineId and sku = preceding-sibling::orderLine/sku and lineTrackingUrl = preceding-sibling::orderLine/lineTrackingUrl,但实际点数的preceding-sibling::orderLine/lineId只是<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:strip-space elements="*"/> <xsl:output indent="yes"/> <xsl:template match="@* | node()"> <xsl:copy> <xsl:apply-templates select="@* | node()"/> </xsl:copy> </xsl:template> <xsl:template match="/order/orderLines/orderLine[sku = preceding-sibling::orderLine/sku and lineId = preceding-sibling::orderLine/lineId]"/> <xsl:template match="/order/orderLines"> <orderLines> <xsl:for-each select="/order/orderLines/orderLine"> <xsl:copy> <xsl:apply-templates select="@* | node()"/> <xsl:choose> <xsl:when test="lineId = preceding-sibling::orderLine[4]/lineId and sku = preceding-sibling::orderLine[4]/sku"> <position> <xsl:value-of select="'5'"/> </position> </xsl:when> <xsl:when test="lineId = preceding-sibling::orderLine[3]/lineId and sku = preceding-sibling::orderLine[3]/sku"> <position> <xsl:value-of select="'4'"/> </position> </xsl:when> <xsl:when test="lineId = preceding-sibling::orderLine[2]/lineId and sku = preceding-sibling::orderLine[2]/sku"> <position> <xsl:value-of select="'3'"/> </position> </xsl:when> <xsl:when test="lineId = preceding-sibling::orderLine[1]/lineId and sku = preceding-sibling::orderLine[1]/sku"> <position> <xsl:value-of select="'2'"/> </position> </xsl:when> <xsl:otherwise> <position><xsl:value-of select="'1'"/></position> </xsl:otherwise> </xsl:choose> </xsl:copy> </xsl:for-each> </orderLines> </xsl:template> </xsl:stylesheet>

所以它只匹配ALL lineIds,而不仅仅是那些具有相同lineId和相同Sku和相同TrackingUrl的那些,而之前的那个,以及之前的那个......等等。我如何限制这个?

修订版

{{1}}

是否有更简洁的方式来执行多个when语句,这仅适用于4个项目,是否有一种方法可以为无限项目执行此操作。目前这很好,但如果它需要扩展我会如何进一步下线呢?

1 个答案:

答案 0 :(得分:0)

我通过使用count()函数解决了这个问题,所以有问题的行看起来像这样:

<xsl:value-of select="count(preceding-sibling::orderLine/lineId)"/>

这会自动将正确的数字填充到<position/>

因此,这意味着整个XSLT看起来像这样:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:strip-space elements="*"/>
    <xsl:output indent="yes"/>

    <xsl:variable name="start" select="'0'"/>

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

    <xsl:template
        match="/order/orderLines/orderLine[sku = preceding-sibling::orderLine/sku and lineId = preceding-sibling::orderLine/lineId]"/>

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


                <xsl:choose>

                    <xsl:when
                        test="lineId = preceding-sibling::orderLine/lineId and sku = preceding-sibling::orderLine/sku and lineTrackingUrl = preceding-sibling::orderLine/lineTrackingUrl">
                        <position>
                            <xsl:value-of select="count(preceding-sibling::orderLine/lineId)"/>
                        </position>
                    </xsl:when>
                    <xsl:otherwise>
                        <position>1</position>
                    </xsl:otherwise>
                </xsl:choose>

            </xsl:copy>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>