зацикливание xslt для другого сценария на основе пар - PullRequest
1 голос
/ 03 января 2012

Согласно предложениям, размещение этого вопроса в отдельной теме. Вопрос является продолжением, по ссылке ниже

XSLT-петля-кол-контекста-значение-из-топ-XML

Мы хотели выдать приведенный ниже xml в качестве выходного (некоторые изменения в выходном xml). тег «ошибки и предупреждения» должен присутствовать в случае, если имеется хотя бы одна ошибка или предупреждение, тег «аллергены», если присутствует хотя бы одна ошибка, тег «все предупреждения», если присутствует хотя бы одно предупреждение

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

1 Ответ

1 голос
/ 03 января 2012

Это преобразование :

<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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...