2014-06-11 129 views
0

我有一個XML一旦應用XSLT模板

<root> 
    <foo>Hello</foo> 
    <bar>World</bar> 
</root> 

和模板

<xsl:template match="foo"> 
    <div> 
     <span><xsl:value-of select="." /></span> 
     <xsl:apply-templates select="//bar" mode="inner" /> 
    </div> 
</xsl:template> 

<xsl:template match="bar"> 
    <span><xsl:value-of select="." /></span> 
</xsl:template> 

<xsl:template match="bar" mode="inner"> 
    <span><xsl:value-of select="." /></span> 
</xsl:template> 

預計

<div> 
    <span>Hello</span> 
    <span>World</span> 
</div> 

實際

<div> 
    <span>Hello</span> 
    <span>World</span> 
</div><span>World</span> 

我沒有可能阻止塊的輸出。此模板用於其他地方

<xsl:template match="bar" /> 

- 編輯 -

我不能覆蓋根模板(這是一個不同的抽象級別)

<xsl:template match="/root"> 
    <xsl:apply-templates /> 
</xsl:template> 

我不能阻止根據需要使用模板bar

<root> 
    <bar>World</bar> 
</root> 

預計

<span>World</span> 

- 真實的例子 -

模板

<?xml version="1.0" encoding="UTF-8" ?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
<xsl:output 
    method="xml" 
    version="1.0" 
    doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN" 
    doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" 
    omit-xml-declaration="yes" 
    media-type="text/html" 
    encoding="utf-8" 
    indent="yes" 
/> 

<xsl:template match="/root"> 
    <html> 
    <head></head> 
    <body> 
     <xsl:apply-templates select="block[@place='main']"/> 
    </body> 
    </html> 
</xsl:template> 

<xsl:template match="block/page"> 
    <div class="page-second"> 
     <xsl:apply-templates select="//block/news" mode="inner" /> 
     <div class="info"> 
      <h1><xsl:value-of select="title" /></h1> 
      <xsl:value-of select="text" /> 
     </div> 
    </div> 
</xsl:template> 

<xsl:template match="block/news"> 
    <div class="clear" /> 
    <div class="news-block"> 
     <h2><xsl:value-of select="title" /></h2> 
     <ul> 
      <xsl:apply-templates select="article" /> 
     </ul> 
    </div> 
</xsl:template> 

<xsl:template match="block/news" mode="inner"> 
    <div class="news-block"> 
     <h2><xsl:value-of select="title" /></h2> 
     <ul> 
      <li><a href="{article/link}"><xsl:value-of select="article/title" /></a></li> 
     </ul> 
    </div> 
</xsl:template> 

<xsl:template match="block/news/article"> 
    <li><a href="{link}"><xsl:value-of select="title" /></a></li> 
</xsl:template> 

</xsl:stylesheet> 

XML 1

<root> 
    <block place="main"> 
     <page> 
      <title>Page title</title> 
      <text>Page text</text> 
     </page> 
    </block> 
    <block place="main"> 
     <news> 
      <title>News title</title> 
      <article> 
       <title>Article 1 title</title> 
       <link>/article-1/</link> 
      </article> 
      <article> 
       <title>Article 2 title</title> 
       <link>/article-2/</link> 
      </article> 
     </news> 
    </block> 
</root> 

預期導致1

<html> 
<head></head> 
<body> 
<div class="page-second"> 
    <div class="news-block"> 
     <h2>News title</h2> 
     <ul> 
      <li><a href="/article-1/">Article 1 title</a></li> 
     </ul> 
    </div> 
    <div class="info"> 
     <h1>Page title</h1> 
     Page text 
    </div> 
</div> 
</body> 
</html> 

XML 2

<root> 
    <block place="main"> 
     <news> 
      <title>News title</title> 
      <article> 
       <title>Article 1 title</title> 
       <link>/article-1/</link> 
      </article> 
      <article> 
       <title>Article 2 title</title> 
       <link>/article-2/</link> 
      </article> 
     </news> 
    </block> 
</root> 

結果2

<html> 
<head></head> 
<body> 
<div class="clear" /> 
<div class="news-block"> 
    <h2>News title</h2> 
    <ul> 
     <li><a href="/article-1/">Article 1 title</a></li> 
     <li><a href="/article-2/">Article 2 title</a></li> 
    </ul> 
</div> 
</body> 
</html> 
+0

當我嘗試http://xsltransform.net/eiQZDbx時,我得到了想要的輸出,但是您需要決定是否要在默認模式下阻止'bar'元素的輸出,或者是否想要變換bar '在該模式下的元素,具有兩個具有相同匹配模式和優先級的模板是XSLT處理器可能通過選擇後一模板來恢復的錯誤。 –

+0

@MartinHonnen具有相同匹配模式的兩個模板不應該是解決方案。 – Bee157

+0

@MartinHonnen我寫道,我不能阻止使用默認模板,因爲它在其他地方使用 – ghost404

回答

1

看着你簡單的「富/條」的例子,你說的是,當「富」的存在,要爲隨後的「酒吧」的信封做一些不同的處理,並且不希望在選擇根的子元素時應用「bar」的其他模板。

在這種情況下,您需要做的就是將模板添加到XSLT中,如果存在「foo」元素則忽略「bar」元素(因爲您知道在這種情況下匹配「foo」的模板正在處理它們與另一個模板)。現在

<xsl:template match="bar[../foo]" /> 

,在實際例子中,「福」元素與「頁」元素作爲孩子,你的「欄」元素「塊」元素與「新聞」子元素「塊」元素。這意味着您只需將此模板添加到現有的XSLT中即可。

<xsl:template match="block[news][../block/page]" /> 

或者,也許這一點,如果「位置」屬性是重要

<xsl:template match="block[@place='main'][news][../block[@place='main']/page]" /> 

所以,它有兩個「頁面」和「新聞」的項目,這將在「根停止<xsl:apply-templates /> 「模板正常處理」新聞「項目。

您的所有其他XSLT可以保持原樣,只需將上面的模板添加到它,它應該做的伎倆。

4

你應該做到以下幾點:

<xsl:template match="/">    
    <xsl:apply-templates select="//foo"/> 
</xsl:template> 
<xsl:template match="foo"> 
    <div> 
     <span><xsl:value-of select="." /></span> 
     <xsl:apply-templates select="//bar" mode="inner" /> 
    </div> 
</xsl:template> 

<xsl:template match="bar"> 
    <span><xsl:value-of select="." /></span> 
</xsl:template> 

<xsl:template match="bar" mode="inner"> 
    <span><xsl:value-of select="." /></span> 
</xsl:template> 

第一個模板(匹配/)將在根級別執行,並且如果不需要子元素將不會被分析。您的解決方案解析了所有內容,並將正確的模板與其關聯。

+0

謝謝,但不幸的是我無法使用此選項。我忘了寫我已經有一個類似於以下的根模板,我也不能改變。 ' – ghost404

+1

@ ghost404 ** 1。**請勿發佈代碼註釋 - 編輯您的問題,而不是。 ** 2。**如果您無法更改產生問題的代碼,那麼您如何期望問題消失? –

+0

你仍然可以添加'' – Bee157

0
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:template match="root"> 
<div> 
<xsl:apply-templates/> 
</div> 
</xsl:template> 

<xsl:template match="foo|bar"> 
<span> 
<xsl:apply-templates/> 
</span> 
</xsl:template> 
</xsl:stylesheet>