2013-02-03 27 views
0

我試圖將xml轉換爲新結構,然後在轉換中處理新結構。我的問題是讓新結構可用作節點集。我在webapp的lib中使用了Tomcat 6和saxon9he。爲了測試新結構的可用性,我創建了以下xsl。xslt 2.0可變元素節點集處理

<?xml version="1.0" encoding="UTF-8"?> 

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

<xsl:output method="xml" omit-xml-declaration="no" indent="yes" encoding="UTF-8"/> 

<xsl:include href="nodeTest.xsl"/> 
<xsl:variable name="theDoc"> 
    <doc> 
    <source>from</source> 
    <source>here</source> 
    <target>to</target> 
    <target>there</target> 
    </doc> 
</xsl:variable> 

<xsl:template match="/"> 
    <xsl:variable name="result1"> 
    <xsl:call-template name="createLinks"> 
    <xsl:with-param name="doc" select="$theDoc/doc/*"/> 
    </xsl:call-template> 
    </xsl:variable> 
input: 
<xsl:value-of select="$theDoc/doc/*"/> 
output: 
<xsl:value-of select="$result1"/> 
</xsl:template> 

</xsl:stylesheet> 

我期望變量theDoc將包含一個有效的節點集,那createLinks模板將處理它作爲一個節點集。這裏是creatlelInks模板;

<?xml version="1.0" encoding="UTF-8"?> 

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

<xsl:template match="node()" mode="makeLink"> 
    <xsl:param name="theSource" select="'source'"/> 
    <xsl:param name="theTarget" select="'target'"/> 
    <xsl:param name="theUsage" select="'usage'"/> 
    <xsl:element name="link" > 
    <xsl:element name="usage" ><xsl:value-of select="$theUsage"/></xsl:element> 
    <xsl:element name="source" ><xsl:value-of select="$theSource"/></xsl:element> 
    <xsl:element name="target" ><xsl:value-of select="$theTarget"/></xsl:element> 
    </xsl:element>  
</xsl:template> 

<xsl:template name="createLinks"> 
<xsl:param name="doc" select="*"/> 
the input doc: 
<xsl:value-of select="$doc"/> 
<xsl:copy> 
    <xsl:element name="Links"> 
     <xsl:apply-templates mode="makeLink" select="."> 
     <xsl:with-param name="theUsage" select="'link from source to target'"/> 
     <xsl:with-param name="theSource" select="$doc/source/*"/> 
     <xsl:with-param name="theTarget" select="$doc/target/*"/> 
     </xsl:apply-templates> 
    </xsl:element> 
    </xsl:copy> 
</xsl:template> 

</xsl:stylesheet> 

執行時,結果如下所示;

<?xml version="1.0" encoding="UTF-8"?> 
input: 
from here to there 
output: 

the input doc: 
fromheretotherelink from source to target 

很明顯,Doc不是節點集。我的理解是,xslt 2.0標準將DOC作爲節點集,而不是結果樹片段。我如何更改這些簡單的xsls來將Doc的內容作爲節點集進行處理?

回答

1

在您的XSLT中有幾個問題阻止它按預期工作。首先是您使用xsl:value-of-來顯示變量的值。例如

<xsl:value-of select="$doc"/> 

這將只顯示節點集的文本值。您應該在這裏使用xsl:copy-of,以返回節點的副本。

<xsl:copy-of select="$doc" /> 

嘗試更換XSL的所有事件:與價值的XSL:複製的-看到你上車。

其次,有一個與你的參數的問題,當你調用「makelink」模板

<xsl:with-param name="theSource" select="$doc/source/*"/> 
<xsl:with-param name="theTarget" select="$doc/target/*"/> 

的*將匹配目標元素的子元素,但他們沒有孩子元素,只有子文本節點(元素是節點,但不是所有節點都是元素!)。你可能想這樣做....

<xsl:with-param name="theSource" select="$doc/source"/> 
<xsl:with-param name="theTarget" select="$doc/target"/> 

事實上,即使是不會因爲你是如何調用模板

<xsl:call-template name="createLinks"> 
    <xsl:with-param name="doc" select="$theDoc/doc/*"/> 
</xsl:call-template> 

調用它這樣的工作意味着目標是頂級元素。你可能想這樣做,而不是...

<xsl:call-template name="createLinks"> 
    <xsl:with-param name="doc" select="$theDoc/doc"/> 
</xsl:call-template> 
+0

copy-of did顯示我期望的結果 - 在修改選擇語法之後,如您所指出的那樣...謝謝 – user2037942

2

這我不清楚你怎麼會到你的結論:

「很明顯,theDoc不是一個節點集我的理解是,。 xslt 2.0標準將DOC作爲節點集,而不是結果樹片段。如何更改這些簡單的xsls來將Doc的內容作爲節點集進行處理?「

這裏的第一個問題是使用的是XSLT 1.0數據模型的術語。在2.0中,不存在節點集,只有序列,且有作爲結果樹片段沒有這樣的事情。

值。的$ theDoc是一個文檔節點此文檔節點有一個名爲doc的子元素,這反過來有四個孩子叫源,源,結果和結果

當你做到這一點。

<xsl:value-of select="$doc"/> 

它輸出該文檔節點的字符串值,這是後代文本節點的連接,即fromheretothere

當你這樣做:

<xsl:value-of select="$result1"/> 

你輸出的RESULT1 $,這本身就是一個文檔節點的字符串值;這個文檔節點有一個稱爲鏈接的子節點,它有三個子節點,稱爲用法,源和目標; usage元素具有文本內容'從源到目標的鏈接',並且源元素和目標元素都是空的。他們是空的原因是表達式$doc/source/*$doc/target/*什麼也沒有選擇;他們沒有選擇任何東西,因爲$ doc有一個叫doc的孩子;來源和目標元素是其孫子。

+0

感謝您的解釋 – user2037942