2012-04-26 119 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

相關問題