2009-07-15 16 views
4

我在我的申請Servlet過濾器截獲所有傳入的請求,並試圖從輸入的XML剝離空格和寫入所得到的「乾淨」 XML到響應。我正在使用XSLT來實現這一點。請參閱下面的XSLT:XSLT:的<xsl:帶狀空間>不起作用

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

<xsl:output method="xml" omit-xml-declaration="no" indent="yes"/> 
<xsl:strip-space elements="*"/> 

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

但是,這不按預期方式工作。生成的XML是一樣的原始XML(儘管使用<的xsl:帶狀空間元素=「*」 />在樣式表

請幫我得到這個權利

問候,
。 - 阿希什

回答

14

從原來的問題使用XSLT ,一個<xsl:template match="text()"><xsl:value-of select="normalize-space(.)"/></xsl:template>應該做的伎倆。

17

目前尚不清楚你想要得到什麼作爲輸出,並從擺在首位xsl:strip-whitespace期待什麼,但有一點要注意的是,它不會刪除所有空白,但只。即,其被認爲是在「通常的」規則微不足道特別是,從XSLT 1.0規格:

文本節點永遠不會剝奪,除非它僅包含空格字符。

因此,舉例來說,這樣的:

<foo> 
    <bar> </bar> 
</foo> 

將被剝離下來:

<foo><bar/></foo> 

,因爲它有3只空白文本節點(<foo><bar>之前,之間<bar></bar>,經過</bar></foo>之前)。

還要注意的是,因爲你在你的樣式表有<xsl:output indent="yes">,它最終會被轉化爲:

<foo> 
    <bar/> 
<foo> 

輸出。

在另一方面,這樣的:

<foo> 
    text1 
    <bar> text2 </bar> 
    text3 
</foo> 

不會在所有被剝奪,因爲它包含了所有的文本節點不是純粹的空白節點。

+1

感謝這樣一個複雜的解釋帕維爾。事實上,我對功能的理解是錯位的。 現在,因爲這是不可能的,是有辦法「裝飾」的使用XSLT樣式表中的所有文本節點的值。 – Vini 2009-07-15 22:27:50

+0

@Winnie - 你有沒有找到一個解決方案來修剪複製節點中的文本? – 2012-07-06 17:31:08

2

添加此爲第二個答案,因爲在第一個的解釋仍然是(希望)足夠的信息,以保持它。

假設通過「微調」你的意思是「刪除所有空白開盤後和結束標記之前立即」,那麼以下附加模板規則應該做的伎倆:

<xsl:variable name="whitespace">&#x20;&#x9;&#xD;&#xA;</xsl:variable> 

<!-- Trim all whitespace at beginning of string --> 
<xsl:template name="trim-start"> 
    <xsl:param name="text"/> 
    <xsl:variable name="first-char" select="substring($text, 1, 1)" /> 
    <xsl:choose> 
    <xsl:when test="contains($whitespace, $first-char)"> 
     <xsl:call-template name="trim-start"> 
     <xsl:with-param name="text" select="substring($text, 2)" /> 
     </xsl:call-template> 
    </xsl:when> 
    <xsl:otherwise> 
     <xsl:value-of select="$text" /> 
    </xsl:otherwise> 
    </xsl:choose> 
</xsl:template> 

<!-- Trim all whitespace at end of string --> 
<xsl:template name="trim-end"> 
    <xsl:param name="text"/> 
    <xsl:variable name="last-char" select="substring($text, string-length($text), 1)" /> 
    <xsl:choose> 
    <xsl:when test="contains($whitespace, $last-char)"> 
     <xsl:call-template name="trim-end"> 
     <xsl:with-param name="text" select="substring($text, 1, string-length($text) - 1)" />   </xsl:call-template> 
     </xsl:call-template> 
    </xsl:when> 
    <xsl:otherwise> 
     <xsl:value-of select="$text" /> 
    </xsl:otherwise> 
    </xsl:choose> 
</xsl:template> 

<xsl:template match="text()"> 
    <xsl:call-template name="trim-start"> 
    <xsl:with-param name="text"> 
     <xsl:call-template name="trim-end"> 
     <xsl:with-param name="text" select="."> 
     </xsl:call-template> 
    <xsl:param> 
    </xsl:call-template> 
</xsl:template>