xslt循环基于对的不同场景

时间:2012-01-02 20:48:21

标签: xml xslt xpath

根据建议,将此问题发布在单独的帖子中。问题是延续,到下面的链接

xslt-loop-count-context-value-from-top-xml

我们想要生成以下xml作为输出(outputxml中的一些更改)。标签,"错误和警告"应该出现以至少出现一个错误或警告,"过敏"当至少存在一个错误时标记,"所有警告"当至少出现一个警告时标记

<Root>
  <errorsandwarnings>
    <allerrors>
      <error>apple</error>
      <error>apple</error>
    </allerrors>
    <allwarnings>
      <warning>apple</warning>
    </allwarnings>
  </errorsandwarnings>
  <success>apple</success>
</Root>

1 个答案:

答案 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:variable name="vErrors" select=
     "/*/Envelope[position() mod 2 = 1]
                   [(.|following-sibling::Envelope[1])
                                          /criticalerror
                   ]"/>

     <xsl:variable name="vWarnings" select=
     "/*/Envelope[position() mod 2 = 1]
                   [(.|following-sibling::Envelope[1])
                                              /milderror
                   ]"/>

     <xsl:variable name="vErrorsWarnings" select=
     "$vErrors | $vWarnings"/>

     <xsl:variable name="vSuccess" select=
        "/*/Envelope
            [position() mod 2 = 1]
              [not((.|following-sibling::Envelope[1])
                    /*[self::criticalerror or self::milderror]
                  )
              ]
     "/>

     <xsl:template match="/*">
         <Root>
           <xsl:if test="$vErrorsWarnings">
            <errorsandwarnings>
             <xsl:apply-templates select="$vErrors"/>
             <xsl:apply-templates select="$vWarnings"/>
            </errorsandwarnings>
           </xsl:if>

           <xsl:apply-templates select="$vSuccess"/>
         </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
        ][1]">
       <allerrors>
         <xsl:apply-templates mode="error" select="$vErrors"/>
       </allerrors>
     </xsl:template>


     <xsl:template match="Envelope" mode="error">
      <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)
        ][1]">
       <allwarnings>
         <xsl:apply-templates mode="warning" select="$vWarnings"/>
       </allwarnings>
     </xsl:template>

     <xsl:template match="Envelope" mode="warning">
      <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>
   <errorsandwarnings>
      <allerrors>
         <error>apple</error>
         <error>apple</error>
      </allerrors>
      <allwarnings>
         <warning>apple</warning>
      </allwarnings>
   </errorsandwarnings>
   <success>apple</success>
</Root>