2011-06-22 14 views
15

Zadeklarowałem zmienną w moim pliku .xsl. Teraz chcę zaktualizować starszą wartość o nową wartość. Na przykład:Jak zaktualizować wartość zmiennej w 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

Czy możesz podać przykładowy plik xml i może opisać, co chcesz z nim zrobić? – Chris

+0

@Chris: Dzięki, zaktualizuję go teraz – Saravanan

+0

@Chris: Proszę zobaczyć ... – Saravanan

Odpowiedz

16

Jeśli zdarza się, że takie zachowanie jest potrzebne w transformacji, oznacza to, że prawdopodobnie trzeba zmienić ogólny "projekt" tego. Trudno również uzyskać to, co próbujesz zrobić bez wyświetlania dokumentu wejściowego i pożądanych danych wyjściowych.

Ponieważ nie można aktualizować zmiennych, trzeba ponownie przemyśleć kod. Wzór (który jestem w stanie wyobrazić) najbliższy Twojej prośbie jest taki:

<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

Nie możesz. XSLT jest funkcjonalnym językiem programowania, więc zmiennych nie można modyfikować. Użyj rekursji, aby zrobić to, co chcesz.

+0

dzięki .. i jestem nowy do xslt.how do korzystania z rekursji tutaj, aby rozwiązać ten problem – Saravanan

+0

Proszę opisać problem, który chcesz rozwiązać: to jest transformacja z wejściowego dokumentu XML do wyjściowego dokumentu XML. Nie możemy odwrócić inżynierii Twoich wymagań od nieprawidłowego kodu. –

Powiązane problemy