xslt循环计数上下文,顶部xml中的值 [英] xslt loop count context, value from top xml

查看:81
本文介绍了xslt循环计数上下文,顶部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>

我不确定如何使它与xslt一起使用. xml文件中总是出现偶数次的信封"元素,原因是,xml将基于成对(第一和第二,第三和第四等)向我们指示成功,错误或警告.最高优先级是"criticalerror"元素,即,如果该元素存在于该对中,则该对被视为错误,则该元素也可能出现两次.

下一个优先级进入轻度错误"元素,该元素代表警告.第三优先级进入成功"元素.因此,只有当两个都包含成功"时,才被视为成功.

对于上述情况,第一对是成功,第二对是错误,第三对是错误,第四对是警告.有两个错误,一个成功,一个警告.这将产生如下所示的xml.同样,错误具有更高的优先级(在xml中首先发生),其次警告

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

现在,对于具有上述xml的每个动作,对于每个配对的场景(成功,错误和警告),每个动作都有三个(这就是我的设计方式),这是数据能力中的一个动作

要使我的每一次操作都成功,我需要从顶部xml中获取"ineed"元素,该元素对应于成功对(即"apple"),可以在一对或两个中的一个或两个中发生顶级xml.一对相同,但是可以同时出现在一个或两个中.

我仅有的是上下文循环计数变量(在本例中为1),表示成功,它将针对所有成功场景进行迭代

针对错误情况的提示(在这种情况下循环2次),需要从顶部xml获取相应的"ineed"元素.循环计数变量1,下一次循环计数变量为2

在警告情况下也有所不同.

解决方案

这是一个完整的解决方案:

<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. 在两个xsl:sort指令中指定了输出元素处理结果的顺序(在xsl:apply-templatesselect属性中指定的节点列表中)-先出错,然后是警告,然后再进行其他操作(成功).

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

  5. 调用名为getTitle的模板,以输出包含在各个Envelope元素对中的第一个非空ineed元素的所需字符串值.

<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>

Hi,

I am not sure how to get this working with xslt. The xml file has "Envelope" elements always in even number of occurences, the reason being, the xml will indicate us success, error or warning based on pairs(first and second, third and fourth etc). The top priority is for "criticalerror" element, that is, if this element is present in the pair, the pair is considered as error, the element can occur twice as well.

The next priority goes to "milderror" element which stands for warning. The third priority goes to "success" element. Therefore only if both contains "success" in the pair, considered as success.

For the above case first pair is success, second one is an error, third one is an error, fourth one is a warning. There are two errors, one success and one warning. This will produce an xml like below. Again, error is having higher priority(occurs first in xml), warning next

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

Now I have a for each action with the above xml, for each paired scenarios(success, error and warning), there are three for each actions(that is how my design is ), which is an action in datapower

Coming to my success for each action, I need to get the "ineed" element from the top xml, corresponding to the success pair, which is "apple", this can occur in either one or both, within a pair of top xml. It is same for a pair, however can occur in either one, or both.

All I have is the context loopcount variable(1 in this case), for success, which is going to iterate for all success scenario

Similary for error scenario(looping 2 times in this case), need to get the corresponding "ineed" element from top xml. Loopcount variable 1, next time loopcount variable is 2

Samething for warning scenario as well.

解决方案

Here is a complete solution:

<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>

when this transformation is applied on the provided XML document:

<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>

the wanted, correct result is produced:

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

Explanation:

  1. No <xsl:for-each> is used, only <xsl:apply-templates>.

  2. Templates are explicitly applied only on the first Envelope of each pair of Envelope elements.

  3. The order in which the result of processing the elements (in the node-list specified in the select attribute of xsl:apply-templates) is output, is specified in two xsl:sort instructions -- first go errors, then warnings, then anything else (success).

  4. We use the fact that when booleans are sorted, false() precedes true().

  5. The template named getTitle is called to output the wanted string value of the first non-empty ineed element contained in the respective pair of Envelope elements.

这篇关于xslt循环计数上下文,顶部xml中的值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆