我有下面的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">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#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">&#160;&#160;&#160;&#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.
虽然模板被调用一次,但是重复了。请让我知道我哪里错了。
由于
答案 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>