2011-06-22 10 views
15

He declarado una variable en mi archivo .xsl. Ahora quiero actualizar el valor anterior con un nuevo valor. Por ejemplo:¿Cómo actualizar el valor de la variable en xslt?

<?xml version="1.0" encoding="iso-8859-1"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
           xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"> 

<xsl:output method="html" indent="yes"/> 

    <xsl:template match="/"> 

    <Document> 
     <xsl:variable name="topLevelHeadings" select = "//w:body/w:p[w:pPr[w:pStyle[@w:val='Heading1']]]"/> 
     <xsl:variable name="beforeHeading" select="false()"/> 


     <xsl:choose> 

     <xsl:when test="$beforeHeading"> 
      <xsl:apply-templates select="//w:body/w:p"> 
      <xsl:with-param name="scope" select="count(//w:body/child::*)-1"/> 
      </xsl:apply-templates> 
     </xsl:when> 

     <xsl:when test="$topLevelHeadings"> 
      <xsl:variable name="beforeHeading" select="true()"/> 
      <xsl:apply-templates select="$topLevelHeadings"> 
       <xsl:with-param name="scope" select="count(//w:body/child::*)-1"/> 
      </xsl:apply-templates> 
     </xsl:when> 

     <xsl:otherwise> 
      <xsl:apply-templates select="//w:body/w:p[w:r[w:t]]"> 
       <xsl:with-param name="scope" select="count(//w:body/child::*)-1"/> 
      </xsl:apply-templates> 
     </xsl:otherwise> 
     </xsl:choose> 
    </Document> 
    </xsl:template> 

    <xsl:template match="w:body/w:p"> 
    <xsl:param name = "scope"/> 
    <xsl:variable name ="index" select="count(preceding-sibling::*)"/> 
    <xsl:if test = "$index &lt;= $scope"> 
     <Paragraph> 
     <xsl:attribute name="index"> 
      <xsl:value-of select="$index" /> 
     </xsl:attribute> 
     <xsl:apply-templates select=".//w:r/w:t"/> 
     </Paragraph> 
    </xsl:if> 
    </xsl:template> 



    <xsl:template match="w:t"> 
     <xsl:value-of select="."/> 
    </xsl:template> 

    <xsl:template match="w:body/w:p"> 
    <xsl:param name = "scope"/> 
    <xsl:variable name ="index" select="count(preceding-sibling::*)"/> 
    <xsl:if test = "$index &lt;= $scope"> 
     <Paragraph> 
     <xsl:attribute name="index"> 
      <xsl:value-of select="$index" /> 
     </xsl:attribute> 
     <xsl:apply-templates select=".//w:r/w:t"/> 
     </Paragraph> 
    </xsl:if> 
    </xsl:template> 

    <xsl:template name="get-para-index"> 
     <xsl:param name="node"/> 
     <xsl:value-of select="count($node/preceding-sibling::*)"/> 
    </xsl:template> 

    <xsl:template match="//w:body/w:p[w:pPr[w:pStyle]]"> 
    <xsl:param name = "scope"/> 

     <xsl:variable name="currIndex" select="count(preceding-sibling::*)"/>    

     <xsl:if test="$currIndex &lt;= $scope"> 

      <!-- Get current heading value --> 
      <xsl:variable name="currHeading" select="./w:pPr/w:pStyle/@w:val"/> 

      <!-- Heading tag --> 
      <xsl:element name="{$currHeading}"> 

      <!-- Get heading text --> 
      <Title> 
       <xsl:attribute name ="index"> 
       <xsl:value-of select="$currIndex"/> 
       </xsl:attribute> 
      <xsl:apply-templates select=".//w:r/w:t"/> 
      </Title> 

      <!-- Get the scope of paragraphs inside this heading --> 
      <xsl:variable name="nextHeading" select="following-sibling::w:p[w:pPr[w:pStyle[@w:val]]][1]"/> 

      <xsl:variable name="paraScope"> 
       <xsl:choose> 
        <xsl:when test="$nextHeading"> 
         <xsl:call-template name="get-para-index"> 
          <xsl:with-param name="node" select="$nextHeading"/> 
         </xsl:call-template> 
        </xsl:when> 
        <xsl:otherwise> 
         <xsl:value-of select="count(//w:body/child::*)"/> 
        </xsl:otherwise> 
       </xsl:choose> 
      </xsl:variable>      

      <!-- Handle paragraphs under this heading -->      
      <xsl:apply-templates select="following-sibling::w:p[//w:r and not(w:pPr[w:pStyle])]"> 
       <xsl:with-param name="scope" select="$paraScope"/> 
      </xsl:apply-templates> 

      <!-- Get the first heading after current node at the same level --> 
      <xsl:variable name="nextSibling" select="following-sibling::w:p[w:pPr[w:pStyle[@w:val=$currHeading]]][1]"/> 

      <!-- Get its index --> 
      <xsl:variable name="nextSiblingIndex"> 
       <xsl:choose> 
       <xsl:when test="$nextSibling">     
        <xsl:call-template name="get-para-index"> 
         <xsl:with-param name="node" select="$nextSibling"/> 
        </xsl:call-template> 
       </xsl:when> 
       <xsl:otherwise> 
       <xsl:value-of select="$scope"/> 
       </xsl:otherwise> 
       </xsl:choose> 
      </xsl:variable> 

      <!-- Set the scope of this node - this will be the smaller of nextSiblingIndex and current scope --> 
      <xsl:variable name="currScope"> 
       <xsl:choose> 
        <xsl:when test="$nextSiblingIndex &lt; $scope"> 
         <xsl:value-of select="$nextSiblingIndex"/> 
        </xsl:when> 
        <xsl:otherwise> 
         <xsl:value-of select="$scope"/> 
        </xsl:otherwise> 
       </xsl:choose> 
      </xsl:variable> 

      <xsl:variable name="nextHead" select="concat('Heading', number(substring-after($currHeading, 'Heading'))+1)"/>    

      <!-- Get a list of child nodes (headings) for the current node --> 
      <xsl:variable name="nextLevelHeadings" select="following-sibling::w:p[w:pPr[w:pStyle[@w:val=$nextHead]]]"/>    

      <!-- Apply recursively for next level headings within the scope --> 
      <xsl:apply-templates select="$nextLevelHeadings"> 
       <xsl:with-param name="scope" select="$currScope"/> 
      </xsl:apply-templates> 

      <!-- Close heading tag --> 
      </xsl:element> 
     </xsl:if> 
    </xsl:template> 

</xsl:stylesheet> 
+0

¿Podría publicar un ejemplo de archivo xml y quizás describir lo que quiere hacer con él? – Chris

+0

@Chris: Gracias, lo actualizaré ahora – Saravanan

+0

@Chris: Por favor, vea esto ... – Saravanan

Respuesta

16

Si sucede que necesita un comportamiento en una transformación, significa que probablemente tenga que cambiar el "diseño" general de la misma. También es difícil obtener lo que intenta hacer sin mostrar su documento de entrada y el resultado deseado.

Como no puede actualizar las variables, debe volver a pensar su código. El patrón (que puedo imaginar) más cercano a su solicitud es algo como esto:

<xsl:template match="/"> 

     <xsl:variable name="topLevelHeadings" select="//w:body/w:p 
       [w:pPr[w:pStyle[@w:val='Heading1']]]"/> 

     <xsl:variable name="beforeHeading"> 
      <xsl:choose> 
       <xsl:when test="$topLevelHeadings"> 
        <xsl:value-of select="true()"/> 
       </xsl:when> 
       <xsl:otherwise> 
        <xsl:value-of select="false()"/> 
       </xsl:otherwise> 
      </xsl:choose> 
     </xsl:variable> 

     <!-- your choose staff --> 

     <!-- for instance --> 
     <xsl:if test="$beforeHeading='true'"> 
      <xsl:message>pass</xsl:message> 
     </xsl:if> 

    </xsl:template> 
12

No puede. XSLT es un lenguaje de programación funcional por lo que las variables no se pueden modificar. Use recursión para hacer lo que quiera en su lugar.

+0

gracias..es nuevo para xslt.cómo usar la recursión aquí para resolver este problema – Saravanan

+0

Por favor, describa el problema que desea resolver: es decir, la transformación de un documento XML de entrada a un documento XML de salida. No podemos aplicar ingeniería inversa a sus requisitos a partir de un código incorrecto. –

Cuestiones relacionadas