2013-02-18 41 views
2

是否有可能做xslt身份轉換,絕對沒有任何東西從源更改?XSLT身份轉換不改變輸出

當我使用以下模板時,ident和linebreaks在輸出中發生更改,我不想對源xml進行任何更改。

XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:template match="@*|node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
</xsl:template> 

INPUT

<S:Envelope 
    xmlns:S="http://www.w3.org/2003/05/soap-envelope" 
    xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" 
    xmlns:f123="http://www.fabrikam123.example/svc53"> 
    <S:Header> 
    <wsa:MessageID> 
     uuid:aaaabbbb-cccc-dddd-eeee-wwwwwwwwwww 
    </wsa:MessageID> 
    <wsa:RelatesTo> 
     uuid:aaaabbbb-cccc-dddd-eeee-ffffffffffff 
    </wsa:RelatesTo> 
    <wsa:To S:mustUnderstand="1"> 
     http://business456.example/client1 
    </wsa:To> 
    <wsa:Action>http://fabrikam123.example/mail/DeleteAck</wsa:Action> 
    </S:Header> 
    <S:Body> 
    <f123:DeleteAck/> 
    </S:Body> 
</S:Envelope> 

OUTPUT

<?xml version="1.0" encoding="UTF-8"?><S:Envelope xmlns:S="http://www.w3.org/2003/05/soap-envelope" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:f123="http://www.fabrikam123.example/svc53"> 
    <S:Header> 
    <wsa:MessageID> 
     uuid:aaaabbbb-cccc-dddd-eeee-wwwwwwwwwww 
    </wsa:MessageID> 
    <wsa:RelatesTo> 
     uuid:aaaabbbb-cccc-dddd-eeee-ffffffffffff 
    </wsa:RelatesTo> 
    <wsa:To S:mustUnderstand="1"> 
     http://business456.example/client1 
    </wsa:To> 
    <wsa:Action>http://fabrikam123.example/mail/DeleteAck</wsa:Action> 
    </S:Header> 
    <S:Body> 
    <f123:DeleteAck/> 
    </S:Body> 
</S:Envelope> 

回答

1

一般來說,不可能100%確信所有的東西都是完全不變的,因爲xslt數據模型根本不保留解析中的所有信息。例如,如果輸入包含&#x3C;,則輸出可能包含&lt;。同樣,CDATA部分也不會保留 - 相鄰文本節點(CDATA部分和普通文本模式)在解析時合併爲一個,而您可以將處理器配置爲使用CDATA來處理某些元素的內容,您不能簡單地將它們保留爲他們是。

還有其他的問題,例如一個事實,即數據模型不<foo></foo><foo/><foo />區分 - 它們都代表從輸入相同的空元素和它們中的任何可以通過在任何一方的表示輸出。正如在你的例子中,開始標籤中的屬性之間的空白不被保留。

但是當然,這些差異是XML工具不應該關心的所有事情,因爲它們是表示完全相同信息集的不同方式。

+0

感謝您輸入非常有用的信息!那麼,我真正想要的是改變wsa的值:在源XML中的元素,並保留源XML的原始格式的其餘部分.. – 2013-02-18 22:04:55

+0

@IsmarSlomic這裏真正的問題是爲什麼?如果您絕對要保留非重要空格的原始格式,那麼XSLT不適合這項工作。 – 2013-02-18 22:10:35

+0

好的,使用XSLT的原因是因爲這是在平臺上使用的唯一工具(IBM Datapower)。保留原始格式的原因是因爲soap:header驗證。 – 2013-02-18 22:17:07

1

XSLT處理器的默認行爲是保留輸入中的空白,並且我剛剛測試的處理器的行爲與規範一致。

但是有問題的空白是輸入文本節點中的空白。

開始標籤中屬性值規範之間的空白以及文檔的序言和結尾處的項目之間的空白(例如註釋和處理指令)不是文本節點,並且不受保存空間的影響設置。實際上,這個空白區域並不是XPath數據模型的一部分,所以處理器可以合理地保留它。

如果有問題的空白帶有信息,您將需要重新查看詞彙表的設計(對於該空白是非常重要的)。如果只是希望在屬性值規範之間存在換行符,則可能需要編寫自定義序列化程序以在輸出中插入這些換行符和縮進。 (如果您的動機是爲了避免將差異程序與空白區別混淆,我的經驗是,您的選擇是在差異之前對空白進行規範化處理,或者在空白變化的情況下獲得比較穩健的差異程序。)祝您好運。

+0

另一種可能性是,空白不會破壞驗證,但XML正在被不是合適的XML解析器的東西讀取 - 臭名昭着的絕望Perl黑客確實存在! – 2013-02-19 08:34:46

2

不,你不能。輸入和輸出XML在產生相同的XML Infoset的意義上是「相同的」,但它們不一定是字節對字節相同的,這不是XSLT可以控制的。

爲什麼你需要這個?如果您試圖輕鬆比較XML文檔,請考慮使用XML Canonicalization。許多XML庫都有一個生成規範XML的方法,並且命令行工具可以很容易地從文件中生成它。