Xslt 如何使用XPath/Xsl将子元素与不同父元素下的相同子元素进行比较?

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

当SupplierId的值发生变化时,我需要使用xsl/xpath(版本1.0)来做一些特殊的事情(为了简化,比如插入一些伪文本)。我需要处理3个变化

  • 第一次点菜时做点什么 (首次出现供应商ID)
  • 在订单ID O3上执行somwthing(供应商ID从S1更改为S2)
  • 在上一个订单上执行某些操作(SupplierId的最后一次出现)
  • 
    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