XSLT 从段落创建列表
XSLT create list from paragraphs
我遇到了来自知名科幻出版商的 HTML 的一段,它试图使用段落作为匿名标签来模仿有序列表。示例如下:
<p class="NL1">1. first list item.</p>
<p class="NL">2. second list item.</p>
<p class="NL">3. third list item.</p>
<p class="NLL">4. last list item.</p>
我想使用 XSLT 将这个令人厌恶的东西转换成真正的有序列表。我试过的是:
<xsl:template name="makeLi">
<li>
<xsl:apply-templates/>
</li>
</xsl:template>
<xsl:template match="p[@class='NL1'
and preceding-sibling::node()[not(self::p[@class='NL1'])]]" >
<ol>
<xsl:call-template name="makeLi"/>
<xsl:apply-templates select="following-sibling::node()[(self::p[@class='NL'])
or (self::p[@class='NLL'])]"/>
</ol>
</xsl:template>
<xsl:template match="p[@class='NL'
and preceding-sibling::node()[not(self::p[@class='NL'])]
and preceding-sibling::node()[not(self::p[@class='NL1'])]]" >
<xsl:call-template name="makeLi"/>
</xsl:template>
<xsl:template match="p[@class='NLL' and preceding-sibling::node()[not(self:::p)]]" >
<xsl:call-template name="makeLi"/>
</xsl:template>
当我应用这个转换时,我最终得到的是:
<ol>
<li>1. first list item.</li>
<li>2. second list item.</li>
<li>3. third list item.</li>
<li>4. fourth list item.</li>
</ol>
<ul>
<li>2. second list item.</li>
<li>3. third list item.</li>
<li>4. fourth list item.</li>
</ul>
如何防止“NL”和“NLL”类被二次处理?
对于 XSLT 1.0,同级递归是正确的选择,而且您的路线是正确的。未经测试,但类似这样:
<xsl:template match="p[@class='NL1']" mode="normal">
<ol>
<xsl:call-template name="makeLi"/>
<xsl:apply-templates select="following-sibling::p[1]" mode="list"/>
</ol>
</xsl:template>
<xsl:template match="p[@class='NL']" mode="list">
<xsl:call-template name="makeLi"/>
<xsl:apply-templates select="following-sibling::p[1]" mode="list"/>
</xsl:template>
<xsl:template match="p[@class='NLL']" mode="list">
<xsl:call-template name="makeLi"/>
</xsl:template>
<xsl:template match="p[@class='NL' or @class='NLL']" mode="normal"/>
我为默认处理模式添加了 mode="normal"
只是为了强调,如果使用默认(未命名)模式,则应将其保留。
我遇到了来自知名科幻出版商的 HTML 的一段,它试图使用段落作为匿名标签来模仿有序列表。示例如下:
<p class="NL1">1. first list item.</p>
<p class="NL">2. second list item.</p>
<p class="NL">3. third list item.</p>
<p class="NLL">4. last list item.</p>
我想使用 XSLT 将这个令人厌恶的东西转换成真正的有序列表。我试过的是:
<xsl:template name="makeLi">
<li>
<xsl:apply-templates/>
</li>
</xsl:template>
<xsl:template match="p[@class='NL1'
and preceding-sibling::node()[not(self::p[@class='NL1'])]]" >
<ol>
<xsl:call-template name="makeLi"/>
<xsl:apply-templates select="following-sibling::node()[(self::p[@class='NL'])
or (self::p[@class='NLL'])]"/>
</ol>
</xsl:template>
<xsl:template match="p[@class='NL'
and preceding-sibling::node()[not(self::p[@class='NL'])]
and preceding-sibling::node()[not(self::p[@class='NL1'])]]" >
<xsl:call-template name="makeLi"/>
</xsl:template>
<xsl:template match="p[@class='NLL' and preceding-sibling::node()[not(self:::p)]]" >
<xsl:call-template name="makeLi"/>
</xsl:template>
当我应用这个转换时,我最终得到的是:
<ol>
<li>1. first list item.</li>
<li>2. second list item.</li>
<li>3. third list item.</li>
<li>4. fourth list item.</li>
</ol>
<ul>
<li>2. second list item.</li>
<li>3. third list item.</li>
<li>4. fourth list item.</li>
</ul>
如何防止“NL”和“NLL”类被二次处理?
对于 XSLT 1.0,同级递归是正确的选择,而且您的路线是正确的。未经测试,但类似这样:
<xsl:template match="p[@class='NL1']" mode="normal">
<ol>
<xsl:call-template name="makeLi"/>
<xsl:apply-templates select="following-sibling::p[1]" mode="list"/>
</ol>
</xsl:template>
<xsl:template match="p[@class='NL']" mode="list">
<xsl:call-template name="makeLi"/>
<xsl:apply-templates select="following-sibling::p[1]" mode="list"/>
</xsl:template>
<xsl:template match="p[@class='NLL']" mode="list">
<xsl:call-template name="makeLi"/>
</xsl:template>
<xsl:template match="p[@class='NL' or @class='NLL']" mode="normal"/>
我为默认处理模式添加了 mode="normal"
只是为了强调,如果使用默认(未命名)模式,则应将其保留。