xslt循环计数上下文,来自顶部xml的值

时间:2012-01-02 13:49:24

标签: xml xslt ibm-datapower

<Root>
  <Envelope>
    <Header>
      <ineed>apple</ineed>
    </Header>
    <success></success>
  </Envelope>
  <Envelope>
    <Header>
      <ineed>apple</ineed>
    </Header>
    <success></success>
  </Envelope>


  <Envelope>
    <Header>
      <ineed>apple</ineed>
    </Header>
    <criticalerror></criticalerror>
  </Envelope>
  <Envelope>
    <Header>
      <ineed>apple</ineed>
    </Header>
    <success></success>
  </Envelope>


  <Envelope>
    <Header>
      <ineed>apple</ineed>
    </Header>
    <criticalerror></criticalerror>
  </Envelope>
  <Envelope>
    <Header>
      <ineed>apple</ineed>
    </Header>
    <criticalerror></criticalerror>
  </Envelope>


  <Envelope>
    <Header>
      <ineed>apple</ineed>
    </Header>
    <milderror></milderror>
  </Envelope>
  <Envelope>
    <Header>
      <ineed>apple</ineed>
    </Header>
    <success></success>
  </Envelope>
</Root>

您好,

我不确定如何使用xslt。 xml文件的“Envelope”元素始终存在偶数次,原因是,xml将根据对(第一,第二,第三和第四等)指示我们成功,错误或警告。最重要的是“criticalerror”元素,也就是说,如果该元素存在于该对中,则该对被视为错误,该元素也可以出现两次。

下一个优先级是“milderror”元素,它代表警告。第三个优先事项是“成功”要素。因此,只有当两者都包含“成功”时才被视为成功。

对于上述情况,第一对成功,第二对是错误,第三对是错误,第四对是警告。有两个错误,一个是成功,一个是警告。这将产生如下的xml。同样,错误具有更高的优先级(首先在xml中出现),然后警告

<Root>
  <error></error>
  <error></error>
  <warning></warning>
  <success></success>
</Root>

现在,对于每个配对场景(成功,错误和警告),每个动作都有上面的xml,每个动作有三个(这就是我的设计),这是datapower中的一个动作

为了我的每个动作的成功,我需要从顶部xml中获取“ineed”元素,对应于成功对,即“apple”,这可以出现在一对或两者中,在一对顶部xml。对于一对,它是相同的,但是可以在任何一个或两个中发生。

我所拥有的只是上下文loopcount变量(在本例中为1),为了成功,将为所有成功场景迭代

类似于错误场景(在这种情况下循环2次),需要从顶部xml获取相应的“ineed”元素。 Loopcount变量1,下一次loopcount变量为2

同样适用于警告场景。

2 个答案:

答案 0 :(得分:1)

这是一个完整的解决方案

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="/*">
     <Root>
      <xsl:apply-templates select="Envelope[position() mod 2 = 1]">
       <xsl:sort select=
         "not((.|following-sibling::Envelope[1])/criticalerror)"/>
       <xsl:sort select=
         "not((.|following-sibling::Envelope[1])/milderror)"/>
      </xsl:apply-templates>
     </Root>
 </xsl:template>

 <xsl:template match=
  "Envelope
    [position() mod 2 = 1
   and
     success
   and
     following-sibling::Envelope[1]/success
    ]">

  <success>
   <xsl:call-template name="getTitle"/>
  </success>
 </xsl:template>

 <xsl:template match=
  "Envelope
    [position() mod 2 = 1
   and
     (.|following-sibling::Envelope[1])/criticalerror
    ]">

  <error>
   <xsl:call-template name="getTitle"/>
  </error>
 </xsl:template>

 <xsl:template match=
  "Envelope
    [position() mod 2 = 1
   and
     (.|following-sibling::Envelope[1])/milderror
   and
     not((.|following-sibling::Envelope[1])/criticalerror)
    ]">

  <warning>
   <xsl:call-template name="getTitle"/>
  </warning>
 </xsl:template>

 <xsl:template name="getTitle">
  <xsl:value-of select=
    "(.|following-sibling::Envelope[1])
         /Header/ineed[normalize-space()]
                                       [1]
    "/>
 </xsl:template>
 <xsl:template match="text()"/>
</xsl:stylesheet>

将此转换应用于提供的XML文档

<Root>
    <Envelope>
        <Header>
            <ineed>apple</ineed>
        </Header>
        <success></success>
    </Envelope>
    <Envelope>
        <Header>
            <ineed>apple</ineed>
        </Header>
        <success></success>
    </Envelope>
    <Envelope>
        <Header>
            <ineed>apple</ineed>
        </Header>
        <criticalerror></criticalerror>
    </Envelope>
    <Envelope>
        <Header>
            <ineed>apple</ineed>
        </Header>
        <success></success>
    </Envelope>
    <Envelope>
        <Header>
            <ineed>apple</ineed>
        </Header>
        <criticalerror></criticalerror>
    </Envelope>
    <Envelope>
        <Header>
            <ineed>apple</ineed>
        </Header>
        <criticalerror></criticalerror>
    </Envelope>
    <Envelope>
        <Header>
            <ineed>apple</ineed>
        </Header>
        <milderror></milderror>
    </Envelope>
    <Envelope>
        <Header>
            <ineed>apple</ineed>
        </Header>
        <success></success>
    </Envelope>
</Root>

产生了想要的正确结果

<Root>
   <error>apple</error>
   <error>apple</error>
   <warning>apple</warning>
   <success>apple</success>
</Root>

<强>解释

  1. 未使用<xsl:for-each>,仅<xsl:apply-templates>

  2. 模板仅明确应用于每对Envelope元素的第一个Envelope

  3. 在两个select中指定处理元素的处理顺序(在xsl:apply-templates xsl:sort属性中指定的节点列表中)的顺序说明 - 首先是错误,然后是警告,然后是其他任何事情(成功)。

  4. 我们使用以下事实:当对布尔值进行排序时,false()先于true()

  5. 调用名为getTitle的模板,以输出相应的ineed元素对中包含的第一个非空Envelope元素的有用字符串值。

答案 1 :(得分:0)

你为什么要使用for-each?据我所知,你不需要循环计数器。你想选择每一对中的第一个元素(我不喜欢这个设计,但让我们放手)就像这样:

然后为这些元素编写模板。在该模板中,您可以使用XPath表达式“following-sibling :: Envelope [1]”获取该对的第二个元素。

如果您需要对奇数元素进行排序,您可能需要执行以下操作:

等等。