当SupplierId的值发生变化时,我需要使用xsl / xpath(版本1.0)来做一些特殊的事情(简化,比如插入一些虚拟文本)。我需要处理3种变化;
<?xml version="1.0" encoding="utf-8"?>
<Orders>
<Order>
<OrderId>O1</OrderId>
<SupplierId>S1</SupplierId>
</Order>
<Order>
<OrderId>O2</OrderId>
<SupplierId>S1</SupplierId>
</Order>
<Order>
<OrderId>O3</OrderId>
<SupplierId>S2</SupplierId>
</Order>
<Order>
<OrderId>O4</OrderId>
<SupplierId>S2</SupplierId>
</Order>
<Order>
<OrderId>O5</OrderId>
<SupplierId>S2</SupplierId>
</Order>
</Orders>
我尝试过使用previous-sibling,follow-sibling等,但还没有发现它。我很感激这个新手问题的任何帮助。
沃利
答案 0 :(得分:1)
这是一种自然而简单的解决方案:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="Order[1]">
First OrderId = <xsl:text/>
<xsl:value-of select="OrderId"/>
</xsl:template>
<xsl:template match="Order[last()]">
Last OrderId = <xsl:text/>
<xsl:value-of select="OrderId"/>
</xsl:template>
<xsl:template match=
"Order[not(position() = 1)]
[not(SupplierId
=
preceding-sibling::Order[1]/SupplierId
)
]">
Changes in Order OrderId = <xsl:text/>
<xsl:value-of select="OrderId"/>
SupplierId = <xsl:text/>
<xsl:value-of select="SupplierId"/>
Previous Order OrderId = <xsl:text/>
<xsl:value-of select=
"preceding-sibling::Order[1]/OrderId"/>
SupplierId = <xsl:text/>
<xsl:value-of select=
"preceding-sibling::Order[1]/SupplierId"/>
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>
在提供的XML文档上应用此转换时:
<Orders>
<Order>
<OrderId>O1</OrderId>
<SupplierId>S1</SupplierId>
</Order>
<Order>
<OrderId>O2</OrderId>
<SupplierId>S1</SupplierId>
</Order>
<Order>
<OrderId>O3</OrderId>
<SupplierId>S2</SupplierId>
</Order>
<Order>
<OrderId>O4</OrderId>
<SupplierId>S2</SupplierId>
</Order>
<Order>
<OrderId>O5</OrderId>
<SupplierId>S2</SupplierId>
</Order>
</Orders>
产生了所需的结果:
First OrderId = O1
Changes in Order OrderId = O3
SupplierId = S2
Previous Order OrderId = O2
SupplierId = S1
Last OrderId = O5
答案 1 :(得分:0)
假设根元素Orders
,匹配每个条件的XPath表达式变为:
一个。 第一个订单(SupplierId首次出现)
XPath 1.0 - /Orders/Order[SupplierId][1]
XPath 2.0 - /Orders/Order[exists(SupplierId)][1]
湾在OrderId O3上(SupplierId从S1更改为S2)
/Orders/Order[OrderId = 'O3' and SupplierId = 'S2']
℃。 在最后一个订单(SupplierId的最后一次出现)
/Orders/Order[SupplierId][last()]
答案 2 :(得分:0)
您可以使用递归逐个降低订单列表,将前一个值与当前值进行比较(解决方案意味着文档顺序已经正确,因为它使用了以下兄弟轴):
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>
<xsl:template match="/Orders">
<xsl:apply-templates select="Order[1]" mode="watch_SupplierId" />
</xsl:template>
<xsl:template match="Order" mode="watch_SupplierId">
<xsl:param name="PrevValue" select="''" />
<xsl:if test="string(SupplierId) != $PrevValue">
<xsl:call-template name="DoSomething" />
</xsl:if>
<xsl:variable name="next" select="following-sibling::Order[1]" />
<xsl:choose>
<xsl:when test="$next">
<xsl:apply-templates select="$next" mode="watch_SupplierId">
<xsl:with-param name="PrevValue" select="string(SupplierId)" />
</xsl:apply-templates>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="concat('last Order found: ', OrderId, ' ')" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="DoSomething">
<xsl:value-of select="concat(
'@SupplierId changed to "'
, SupplierId/text()
, '" in Order '
, OrderId
, ' '
)" />
</xsl:template>
</xsl:stylesheet>
输出:
@SupplierId changed to "S1" in Order O1 @SupplierId changed to "S2" in Order O3 last Order found: O5