2011-06-22 57 views
15

我已经在我的.xsl文件中声明了一个变量。现在我想用新值更新旧值。例如:如何更新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

你能发布一个示例xml文件,也许描述你想用它做什么? – Chris

+0

@Chris:谢谢,我现在更新 – Saravanan

+0

@Chris:请看这个...... – Saravanan

回答

16

如果碰巧你在转换中需要这样的行为,那意味着你可能需要改变它的总体“设计”。在没有显示你的输入文件和想要的输出的情况下,你也很难得到你想要做的事情。

因为你不能更新变量,你必须重新考虑你的代码。最接近你的请求的模式(这是我能够想象的)是这样的:

<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

你不能。 XSLT是一种功能性编程语言,所以变量不能被修改。使用递归来做你想要的。

+0

谢谢..我是新来的xslt.how在这里使用递归来解决这个问题 – Saravanan

+0

请描述你想解决的问题:也就是从输入XML文档到输出XML文档的转换。我们无法从错误的代码中反向设计您的需求。 –