我在XML之下。
<emphasis type="italic">
varying from ti,e to time<star.page>58</star.page>Starch
</emphasis>
和
<para indent="no">
<star.page>18</star.page> Further to same.
</para>
这里我试图在apply-templates
上star.page
,但是如果我采用<xsl:apply-templates select="./*[1][self::star.page]" mode="first"/>
,那么它会在第一种情况下工作正常,但对于第二种情况,如果我使用star.page
<xsl:apply-templates select="./node()[1][self::star.page]" mode="first"/>
case 2
,那么div
将会div
内的case 1
之前出现的star.page <span class="font-style-italic">
varying from ti,e to time<?pb label='58'?><a name="pg_58"></a></span>2<span class="font-style-italic">Starch
</span>
,值正在重复。
以下是DEmos
案例1 - enter link description here 案例2- enter link description here
预期输出如下。
案例1:
<?pb label='18'?><a name="pg_18"></a>
<div class="para">
Further to same.
</div>
案例2:
star.page
这里的条件如下。
para
是父节点的直接子节点(虽然它是emphasis
或pb label
),则必须先创建star.page
,然后再创建标记(案例2)输出)。请让我知道如何解决这些问题的常见解决方案。
答案 0 :(得分:1)
我不清楚你的大部分XSLT在做什么,但我会首先使用命名模板来避免重复代码。为匹配的模板提供名称也没有问题。
<xsl:template match="star.page" name="page">
<xsl:processing-instruction name="pb">
<xsl:text>label='</xsl:text>
<xsl:value-of select="."/>
<xsl:text>'</xsl:text>
<xsl:text>?</xsl:text>
</xsl:processing-instruction>
<a name="{concat('pg_',.)}"/>
</xsl:template>
然后具有“first”模式的模板变为此
<xsl:template match="star.page" mode="first">
<xsl:call-template name="page" />
</xsl:template>
你仍然可以用同样的方式调用它,或者稍微不同的条件也可以使用
<xsl:apply-templates select="star.page[not(preceding-sibling::node())]" mode="first"/>
然后,您只需要一个模板来忽略作为第一个孩子的“star.page”(因为它们已经被明确选中)
<xsl:template match="star.page[not(preceding-sibling::node())]" />
作为简化示例,请为starers尝试此操作
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" />
<xsl:strip-space elements="*" />
<xsl:template match="para|emphasis">
<xsl:apply-templates select="star.page[not(preceding-sibling::node())]" mode="first"/>
<div>
<xsl:choose>
<xsl:when test="./@align">
<xsl:attribute name="class"><xsl:text>para align-</xsl:text><xsl:value-of select="./@align"/></xsl:attribute>
</xsl:when>
<xsl:otherwise>
<xsl:attribute name="class"><xsl:text>para</xsl:text></xsl:attribute>
</xsl:otherwise>
</xsl:choose>
<xsl:apply-templates/>
</div>
</xsl:template>
<xsl:template match="star.page[not(preceding-sibling::node())]" />
<xsl:template match="star.page" name="page">
<xsl:processing-instruction name="pb">
<xsl:text>label='</xsl:text>
<xsl:value-of select="."/>
<xsl:text>'</xsl:text>
<xsl:text>?</xsl:text>
</xsl:processing-instruction>
<a name="{concat('pg_',.)}"/>
</xsl:template>
<xsl:template match="star.page" mode="first">
<xsl:call-template name="page" />
</xsl:template>
</xsl:stylesheet>
请注意这里使用strip-space
,因为严格来说,star.page
不是每个示例中的第一个节点,前面有一个空白节点。
应用于此XML
<root>
<emphasis type="italic">
varying from ti,e to time<star.page>58</star.page>Starch
</emphasis>
<para indent="no">
<star.page>18</star.page> Further to same.
</para>
</root>
以下是输出
<div class="para">
varying from time to time<?pb label='58'??><a name="pg_58"/>Starch
</div>
<?pb label='18'??>
<a name="pg_18"/>
<div class="para"> Further to same.
</div>