2017-04-01 15 views
0

我有一個特定於listitems節點的模板元素。不確定爲什麼當特定模板存在時打印所有文本

XSL

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    version="1.0"> 

    <xsl:output method="text"/> 

    <xsl:template match="listitems"> 
    <xsl:value-of select="@status" /> 
    </xsl:template> 

</xsl:stylesheet> 

XML

<?xml version="1.0" encoding="utf-8"?> 
<?xml-stylesheet type="text/xsl" href="callvsapply.xslt"?> 
<!-- sample XML snippet --> 
<xml> 
    <foo status="No">You are here.</foo> 
    <bar status="Yes">Hello Bar!</bar> 
    <baz status="No">Hello Baz!</baz> 
    <listitems status="Yes" id="13" /> 
    <listitems status="No" id="12" /> 
</xml> 

導致

You are here. 
    Hello Bar! 
    Hello Baz! 
    Yes 
    No 

爲什麼所有的文本打印?我期望的是,是的,不,

回答

3

XSLT有"built-in template rules"一個概念,這是如果沒有相關的模板進行到正在應用模板當前節點定義中使用的模板。

他們看起來像這樣:

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

<xsl:template match="text()|@*"> 
    <xsl:value-of select="."/> 
</xsl:template> 

<xsl:template match="processing-instruction()|comment()"/> 

什麼這些歸結爲是:

  • 如果當前節點是一個元素或根節點,應用模板到所有子節點。
  • 如果當前節點是文本節點或屬性節點,請將其值放在輸出中。
  • 如果當前節點是處理指令或註釋,則不執行任何操作。

所以基本上,如果沒有指定模板,XSLT的默認行爲是將文檔從上到下移動,輸出所有文本節點的值。這就是您所看到的 - 您的XSLT正在輸出遇到的所有文本。

要在您的情況下解決這個問題,有兩種基本方法:

第一種辦法:攔截處理根節點(或文檔元素),並直接針對你想從那裏處理節點:

<xsl:stylesheet 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    version="1.0"> 

    <xsl:output method="text"/> 

    <xsl:template match="/*"> 
    <xsl:apply-templates select="listitems" /> 
    </xsl:template> 

    <xsl:template match="listitems"> 
    <xsl:value-of select="@status" /> 
    </xsl:template> 

</xsl:stylesheet> 

第二條本辦法:覆蓋內置的文本節點處理,使它們的值默認情況下不發送到輸出:

<xsl:stylesheet 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    version="1.0"> 

    <xsl:output method="text"/> 

    <xsl:template match="listitems"> 
    <xsl:value-of select="@status" /> 
    </xsl:template> 

    <xsl:template match="text()" /> 

</xsl:stylesheet> 
1

你必須先刪除所有你不需要打印的元素。

爲此,您可以使用此:

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet 
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
     version="1.0"> 

     <xsl:output method="text"/> 

     <xsl:template match="listitems"> 
       <xsl:value-of select="@status" /> 
     </xsl:template> 

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

</xsl:stylesheet> 
+0

這工作,但是,我米不知道我明白爲什麼。你能再解釋一下發生了什麼? – Rod

+1

在xslt中未處理的所有元素在輸出中反映爲文本,因此我們使用遞歸運行的新模板,並且不生成輸出,因爲沒有在文件中找到xslt定義,並且僅爲找到該模板的那個元素運行。 – Rupesh

相關問題