我正在尝试添加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 个项目,有没有一种方法可以为无限的项目做这件事。目前这很好,但如果需要扩展,我将如何做到这一点?