2013-02-16 93 views
1

我的XSLT:爲什麼XSLT產生意想不到的結果

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

<xsl:template match="soapenv:Body//*"> 
    <xsl:element name="{local-name()}"> 
     <xsl:apply-templates select="@* | *" /> 
     <xsl:value-of select="." /> 
    </xsl:element> 
</xsl:template> 

<xsl:template match="soapenv:Body//@*"> 
    <xsl:attribute name="{local-name()}"> 
     <xsl:value-of select="." /> 
    </xsl:attribute> 
</xsl:template> 

輸入:

<soapenv:Body> 
    <Test asdf="asdfasdf"> 
     <Hope>asdf</Hope> 
    </Test> 
</soapenv:Body> 

輸出:

<Test asdf="asdfasdf"> 
    <Hope>asdf</Hope> 
    asdf 
</Test> 

我的問題是,爲什麼我收到後,多餘的ASDF文本希望元素?

回答

2

因爲你Test元素由<xsl:template match="soapenv:Body//*">,這在輸出創建Test元素匹配,應用模板到其子(複製Hope元素),然後追加包含Test元素本身的字符串值的文本節點 - 這是所有後代文本節點的連接,包括Hope中的一個。

你可以通過使當有問題的元件不具有子元素的<xsl:value-of>只火,無論是在

<xsl:if test="not(*)"> 

包裹,或通過使用一個單獨的模板soapenv:Body//*[*]

2

您解決這個問題似乎想要擺脫名稱空間。 (爲什麼?這實際上不是必須的!

考慮一個更習慣的方法。

<!-- 1) always try to start off with the identity template --> 
<xsl:template match="node() | @*"> 
    <xsl:copy> 
     <xsl:apply-templates select="node() | @*" /> 
    </xsl:copy> 
</xsl:template> 

<!-- 2) only create templates for nodes that need extra processing --> 
<xsl:template match="soapenv:*"> 
    <xsl:element name="{local-name()}"> 
     <xsl:apply-templates select="node() | @*" /> 
    </xsl:element> 
</xsl:template> 

結果與你輸入:

<Body> 
    <Test asdf="asdfasdf"> 
     <Hope>asdf</Hope> 
    </Test> 
</Body> 

編輯:如果你只是想在開始正文內容輸出,使用:

<xsl:template match="/"> 
    <xsl:apply-templates select="soapenv:Envelope/soapenv:Body/*" /> 
</xsl:template> 
相關問題