0

我正在尝试添加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>

你会看到那个test时候是lineId = preceding-sibling::orderLine/lineId and sku = preceding-sibling::orderLine/sku and lineTrackingUrl = preceding-sibling::orderLine/lineTrackingUrl但是实际计数的只是preceding-sibling::orderLine/lineId

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

经过修改的版本

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

是否有一种更简洁的方法来执行多个 when 语句,这只适用于 4 个项目,有没有一种方法可以为无限的项目做这件事。目前这很好,但如果需要扩展,我将如何做到这一点?

4

1 回答 1

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>
于 2012-08-15T10:16:00.857 回答