Xslt 如何使用XPath/Xsl将子元素与不同父元素下的相同子元素进行比较?
当SupplierId的值发生变化时,我需要使用xsl/xpath(版本1.0)来做一些特殊的事情(为了简化,比如插入一些伪文本)。我需要处理3个变化Xslt 如何使用XPath/Xsl将子元素与不同父元素下的相同子元素进行比较?,xslt,xpath,Xslt,Xpath,当SupplierId的值发生变化时,我需要使用xsl/xpath(版本1.0)来做一些特殊的事情(为了简化,比如插入一些伪文本)。我需要处理3个变化 第一次点菜时做点什么 (首次出现供应商ID) 在订单ID O3上执行somwthing(供应商ID从S1更改为S2) 在上一个订单上执行某些操作(SupplierId的最后一次出现) O1 S1 氧气 S1 臭氧 S2 O4 S2 O5 S2 我试过使用前兄弟姐妹、后兄弟姐妹等,但还没有发现。如果你能帮我解决这个新手问题,我将不胜感激 Wa
O1
S1
氧气
S1
臭氧
S2
O4
S2
O5
S2
我试过使用前兄弟姐妹、后兄弟姐妹等,但还没有发现。如果你能帮我解决这个新手问题,我将不胜感激
Wally假设根元素
Orders
,则匹配每个条件的XPath表达式变为:
a第一批订单(供应商ID的第一次出现)
b订单ID O3(供应商ID从S1更改为S2)
c上一次订单(供应商ID的最后一次出现)
假设根元素
Orders
,则匹配每个条件的XPath表达式变为:
a第一批订单(供应商ID的第一次出现)
b订单ID O3(供应商ID从S1更改为S2)
c上一次订单(供应商ID的最后一次出现)
您可以使用递归逐个逐级删除订单列表,并在执行时将上一个值与当前值进行比较(解决方案意味着文档顺序已经正确,因为它使用了以下同级轴):
产出:
@SupplierId changed to "S1" in Order O1
@SupplierId changed to "S2" in Order O3
last Order found: O5
@供应商ID更改为“S1”,顺序为O1
@供应商ID更改为“S2”,顺序为O3
最后找到的订单:O5
您可以使用递归逐个逐级删除订单列表,并在执行时将上一个值与当前值进行比较(解决方案意味着文档顺序已经正确,因为它使用了以下同级轴):
产出:
@SupplierId changed to "S1" in Order O1
@SupplierId changed to "S2" in Order O3
last Order found: O5
@供应商ID更改为“S1”,顺序为O1
@供应商ID更改为“S2”,顺序为O3
最后找到的订单:O5
这是一个自然而简单的解决方案:
<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>
<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
这是一个自然而简单的解决方案:
<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>
<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
您的XML不包含根元素。因此,它的格式不好。另外,您还没有提到正在使用的XPath版本。这使问题变得复杂,因为XPath 2.0带来了许多新功能来简化问题。因此,它的格式不好。另外,您还没有提到正在使用的XPath版本。这使事情变得复杂,因为XPath 2.0带来了许多新功能,简化了事情事实上,我预料到你会这么说。:)+1、非常好。重复访问“前兄弟”轴是否是潜在的性能问题?@Tomalak引用“前兄弟”轴在这种情况下不是问题。前面的兄弟::某些东西[1]需要一个固定的时间,除非有一个糟糕的、非优化的XSLT处理器。@Dimitre:请看我对您对我的答案的评论的回复。。。啊,管它呢!;-)+1、非常好。重复访问“前兄弟”轴是否是潜在的性能问题?@Tomalak引用“前兄弟”轴在这种情况下不是问题。前面的兄弟::某些东西[1]需要一个固定的时间,除非有一个糟糕的、非优化的XSLT处理器。@Dimitre:请看我对您对我的答案的评论的回复。。。啊,管它呢!;-)OP提出了其他问题:如何检测供应商ID何时从上一个订单更改为当前订单。另一个注意事项是,提供的XPath表达式(XPath2.0还有其他问题!)选择的不是第一个订单的SupplierId,而是具有SupplierId@Dimitre:谢谢你的评论。就订单节点的选择而言,根据问题中所述的要求(或至少我对含义的解释),这完全是有意的。为了回归测试我的表达式,我从示例XML中的第一个订单和最后一个订单节点中删除了SupplierId节点。至于节点变化的检测,我假设这将通过代码或OP自己的XSLT实现来完成。OP询问的是其他问题:如何检测SupplierId何时从以前的订单变为当前订单。另一个注意事项是,提供的XPath表达式(XPath2.0还有其他问题!)选择的不是第一个订单的SupplierId,而是具有SupplierId@Dimitre:谢谢你的评论。就订单节点的选择而言,根据问题中所述的要求(或至少我对含义的解释),这完全是有意的。为了回归测试我的表达式,我从示例XML中的第一个订单和最后一个订单节点中删除了SupplierId节点。至于节点变化的检测,我假设可以通过代码或OP自己的XSLT实现来完成。
First OrderId = O1
Changes in Order OrderId = O3
SupplierId = S2
Previous Order OrderId = O2
SupplierId = S1
Last OrderId = O5