虽然模板是唯一的,但文本正在重复

时间:2014-01-06 08:26:13

标签: xslt xslt-2.0

我有下面的XML。

<section level="sect2" number-type="manual">
    <para align="center">
                <phrase>24-2</phrase>
                <content-style font-style="italic">Destroying [or Damaging] property, contrary to section 60(1) of the Crimes Ordinance Cap 200, Laws of Hong Kong.</content-style>
            </para>
</section>

当我应用以下XSLT时

<xsl:template name="para" match="section/para">
        <xsl:choose>
            <xsl:when test="current()/@align=center and ./@differentiation">
                <div class="para align-{@align}">
                    <xsl:apply-templates/>
                </div>
            </xsl:when>
                   <xsl:when test="current()/@align=center and not(./@differentiation)">
                <div class="para align1-{@align}">
                    <xsl:apply-templates/>
                </div>
            </xsl:when>
              <xsl:when test="current()/@align and ./phrase[1]">
                <div class="para new">
                     <xsl:apply-templates/>
                </div>
            </xsl:when>
                    <xsl:when test="current()/@align">
                <div class="para align-{@align}">
                    <xsl:apply-templates/>
                </div>
            </xsl:when>
            <xsl:otherwise>
                <div class="para">
                    <xsl:apply-templates/>
                </div>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>



<xsl:template match="text()">

 <xsl:analyze-string select="." regex="(([Cc]hapter)\s(\d+))">
      <xsl:matching-substring>


      </xsl:matching-substring>
      <xsl:non-matching-substring>
        <xsl:analyze-string select="." regex="([0-9]+)\.([0-9]+)">
          <xsl:matching-substring>
          <xsl:variable name="num">
          <xsl:value-of select="string-length(regex-group(2))"/>
          </xsl:variable>

            <a
              href="{concat('er:#ABHK_CH_',format-number(number(regex-group(2)),'00'),'/P',format-number(number(regex-group(2)),'0'),'-',regex-group(3))}">
              <xsl:value-of select="."/>
            </a>          





          </xsl:matching-substring>
          <xsl:non-matching-substring>
            <xsl:value-of select="."/>
          </xsl:non-matching-substring>
        </xsl:analyze-string>
      </xsl:non-matching-substring>
    </xsl:analyze-string>



</xsl:template>

    <xsl:template name="phrase" match="phrase">
    <xsl:variable name="phrl">
        <xsl:value-of select="string-length(text())"/>
    </xsl:variable>
        <xsl:variable name="phrase">
            <xsl:value-of select="concat('P',text())"/>
        </xsl:variable>
        <xsl:variable name="newphrase" select="translate($phrase,'.','-')"/>
        <a>
            <xsl:attribute name="name">
                <xsl:value-of select="$newphrase">
                </xsl:value-of>
            </xsl:attribute>
        </a>
        <xsl:choose>
        <xsl:when test="../@align">
              <span class="phrase">
            <xsl:value-of select="current()"/>
        </span>
            <span class="align-center">
            <xsl:apply-templates select="following-sibling::node()[1]"/>
            </span>
            </xsl:when>
            <xsl:when test="$phrl=3">
                  <span class="phrase">
            <xsl:value-of select="current()"/>
        </span>
    <xsl:text disable-output-escaping="yes">&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;</xsl:text>
            </xsl:when>
            <xsl:when test="$phrl=4">
                  <span class="phrase">
            <xsl:value-of select="current()"/>
        </span>
    <xsl:text disable-output-escaping="yes">&amp;#160;&amp;#160;&amp;#160;&amp;#160;</xsl:text>
            </xsl:when>

        <xsl:otherwise>
        <span class="phrase">
            <xsl:value-of select="current()"/>
        </span>
        </xsl:otherwise>
        </xsl:choose>


    </xsl:template>

     <xsl:template match="content-style">
<xsl:choose>
    <xsl:when test="./@format">
        <span class="{concat('format-',@format)}">
              <xsl:apply-templates/>
        </span>
    </xsl:when>
    <xsl:otherwise>
     <xsl:variable name="fontStyle">
            <xsl:value-of select="concat('font-style-',@font-style)"/>
        </xsl:variable>
        <span class="{$fontStyle}">
        <xsl:choose>
                                    <xsl:when test="../@align">
                                         <xsl:value-of select="."/>
                                    </xsl:when>
                                    <xsl:otherwise>
                                      <xsl:value-of select="."/>
            <xsl:apply-templates select="para"/>
                                    </xsl:otherwise>
                                </xsl:choose>

        </span>
    </xsl:otherwise>
</xsl:choose>    
    </xsl:template>

我得到的输出是

24-2 Destroying [or Damaging] property, contrary to section 60(1) of the Crimes Ordinance Cap 200, Laws of Hong Kong. Destroying [or Damaging] property, contrary to section 60(1) of the Crimes Ordinance Cap 200, Laws of Hong Kong.

此处Destroying [or Damaging] property, contrary to section 60(1) of the Crimes Ordinance Cap 200, Laws of Hong Kong. 虽然模板被调用一次,但是重复了。请让我知道我哪里错了。

由于

1 个答案:

答案 0 :(得分:1)

在匹配 para 元素的模板中,您正在执行此操作

<xsl:apply-templates/>

这将查看 para 元素的子节点,并选择与它们匹配的模板。由于其中一个子元素是内容风格,这显然会应用与其匹配的模板。

但是,在匹配词组的模板中(这是的另一个孩子),您执行此操作(在的情况下) element有一个对齐属性,这是在这里做的)

<xsl:apply-templates select="following-sibling::node()[1]"/>

以下兄弟是内容风格,因此这也将使用该模板。因此,匹配内容样式的模板会被调用两次。

一个解决方案是匹配的模板,这样就不会执行<xsl:apply-templates/>,而是明确忽略跟随词组元素的节点

<xsl:apply-templates select="*[not(preceding-sibling::*[1][local-name()='phrase'])]" />

尝试使用此模板 para 而不是

<xsl:template name="para" match="section/para">
    <xsl:choose>
        <xsl:when test="current()/@align=center and ./@differentiation">
            <div class="para align-{@align}">
                <xsl:apply-templates select="*[not(preceding-sibling::*[1][local-name()='phrase'])]" />
            </div>
        </xsl:when>
               <xsl:when test="current()/@align=center and not(./@differentiation)">
            <div class="para align1-{@align}">
                <xsl:apply-templates select="*[not(preceding-sibling::*[1][local-name()='phrase'])]" />
            </div>
        </xsl:when>
          <xsl:when test="current()/@align and ./phrase[1]">
            <div class="para new">
                  <xsl:apply-templates select="*[not(preceding-sibling::*[1][local-name()='phrase'])]" />
            </div>
        </xsl:when>
                <xsl:when test="current()/@align">
            <div class="para align-{@align}">
                <xsl:apply-templates select="*[not(preceding-sibling::*[1][local-name()='phrase'])]" />
            </div>
        </xsl:when>
        <xsl:otherwise>
            <div class="para">
                <xsl:apply-templates/>
            </div>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>