我正在尝试将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
只是<?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个项目,是否有一种方法可以为无限项目执行此操作。目前这很好,但如果它需要扩展我会如何进一步下线呢?
答案 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>