web-dev-qa-db-ja.com

xsltの変数値を更新する方法は?

.xslファイルで変数を宣言しました。次に、古い値を新しい値に更新します。例えば:

<?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>
16
Saravanan

トランスフォームでこのような動作が必要になった場合、おそらく全体的な「デザイン」を変更する必要があることを意味します。また、入力ドキュメントと必要な出力を表示せずに、実行しようとしているものを取得することも困難です。

変数を更新できないため、コードを再考する必要があります。あなたのリクエストに最も近いパターン(私が想像できる)は、このようなものです:

    <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>
17
Emiliano Poggi

できません。 XSLTは関数型プログラミング言語であるため、変数は変更できません。代わりに再帰を使用して、必要なことを実行してください。