2012-04-26 118 views
1

我目前有一个简单的标记,主要代表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> 

此方法可以防止通过传递任何子标签,但我不能确定,我怎么能解决这个搞定。

任何帮助,非常感谢! Dan

+0

您能否提供一些关于_markup_模板的更多信息?目前,我看不到_li_元素的子元素为什么会丢失的任何原因。由于您将整个_li_元素传递给模板(''),所有后代在模板中仍然可用。 – Martin 2012-04-26 08:43:56

+0

我使用http://www.jenitennison.com提供的markup.xsl。本质上,markup.xsl通过关键字库(keywords.xml)查找并将其与正在查看的文档进行比较,如果匹配成功,它将使用以下代码: \t的 \t \t 2012-04-26 09:00:59

+0

http://www.jenitennison.com/xslt/utilities/markup.xml – 2012-04-26 09:02:29

回答

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>

  1. 它完全遍历输入,复制它,除非更具体的模板匹配当前节点。
  2. 这意味着你只需要为你想要的节点编写模板变更。在这种情况下,匹配文本节点效果最好,因为它们不能嵌套子节点。
  3. 避免命名模板,如<xsl:template name="List">。这是“推式”XSLT,即它是必不可少的,并且往往导致相当笨拙的结果。
  4. <xsl:template match="li//text()">节点从流中拉出来并执行比复制它们更复杂的操作。这是“拉式”XSLT,即模板匹配。它通常更容易处理并生成更干净的XSLT代码。
  5. 当然,您不受限于<li>元素内的文本节点。只需更改匹配表达式即可影响其他节点。

假设您要将所有<b>节点变为<strong>而不中断任何其他模板。随着拉风,这是因为这很容易:

<xsl:template match="b"> 
    <strong> 
    <xsl:apply-templates select="node() | @*" /> 
    <strong> 
</xsl:template> 

还要注意的是,当你做<xsl:call-template>当前节点不会改变。因此不需要将当前节点传递给被调用的模板。

+0

您'是一颗明星!非常感谢你。 – 2012-04-26 09:13:11

+0

@丹尼尔不客气。 – Tomalak 2012-04-26 09:26:38

相关问题