我目前有一个简单的标记,主要代表HTML。
以下是
的摘录<li>Make this <b>Bold</b></li>
我当然可以使用<xsl:copy-of>
来确保<b>
标记通过并自动显示为粗体,但是我遇到了问题。
我正在使用另一个XSL来检查关键字或短语存储库的标记,如果它们存在,则会创建链接。
以下是我的XSL
<xsl:template name="List" match="li">
<li>
<xsl:call-template name="markup">
<xsl:with-param name="text" select="."/>
<xsl:with-param name="phrases" select="document('../../documents/main/keywords.xml')/keywords/keyword"/>
<xsl:with-param name="first-only" select="false()"/>
</xsl:call-template>
</li>
</xsl:template>
此方法可以阻止任何子标记传递,但我不确定如何解决这个问题。
非常感谢任何帮助! 丹
答案 0 :(得分:1)
问题是你的链接创建模板做错了。
正确的做法是使用标识模板并为<li>
元素的文本节点后代创建专用模板。
试试这个:
<xsl:variable
name="keywords"
select="document('../../documents/main/keywords.xml')/keywords/keyword"
/>
<!-- the identity template does copies of everything not matched otherwise -->
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="node() | @*" />
</xsl:copy>
</xsl:template>
<!-- text nodes in <li> elements get special treatment -->
<xsl:template match="li//text()">
<xsl:call-template name="markup">
<xsl:with-param name="phrases" select="$keywords"/>
<xsl:with-param name="first-only" select="false()"/>
</xsl:call-template>
</xsl:template>
<!-- marks up the current node -->
<xsl:template name="markup">
<xsl:with-param name="phrases" />
<xsl:with-param name="first-only" select="true()" />
<!-- you can use . here - no need to pass in a $text param -->
</xsl:template>
身份模板是成功解决此类问题的关键。它处理透明地复制<li>
和<b>
。
<xsl:template name="List">
之类的命名模板。这是“推式”XSLT,即它必不可少,往往导致相当笨拙的结果。<xsl:template match="li//text()">
将节点拉出流,并执行比复制它们更复杂的操作。这是“拉式”XSLT,即模板匹配。它通常更容易处理并生成更清晰的XSLT代码。<li>
元素中的文本节点。只需更改匹配表达式即可影响其他节点。假设您希望将所有<b>
个节点都转换为<strong>
,而不会中断任何其他模板。使用拉式,这很简单:
<xsl:template match="b">
<strong>
<xsl:apply-templates select="node() | @*" />
<strong>
</xsl:template>
另请注意,执行<xsl:call-template>
时当前节点不会更改。因此,无需将当前节点传递给被调用的模板。