2014-09-04 13 views
0

我有2臺機器上有相同的java代碼。代碼是關於使用文檔構建器構建一個xml文檔,以及關於使用變換器將該文檔轉換爲字符串。兩者都使用factory.newInstance()實例化:XML命名空間與DocumentBuilder/Transformer的不同實現有所不同

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
DocumentBuilder db = dbf.newDocumentBuilder(); 

TransformerFactory tff = TransformerFactory.newInstance(); 
Transformer tf = tff.newTransformer(); 

但是,我注意到它們的行爲不同。一臺機器在文檔中插入節點正確地將空名稱空間變爲名稱空間,其名稱等於空字符串。在另一臺機器上,這不會發生,並且沒有插入名稱空間,而該元素使用父級的名稱空間。

所以我比較了工廠和生產商/變壓器的實際類/類加載器,它們確實不同。下面是正確的輸出日誌文件:

DocumentBuilderFactory class name:  com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl 
DocumentBuilderFactory class loader:  null 
DocumentBuilderFactory class package:  package com.sun.org.apache.xerces.internal.jaxp, Java Platform API Specification, version 1.7 

DocumentBuilder class name:    com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl 
DocumentBuilder class loader:   null 
DocumentBuilder class package:  package com.sun.org.apache.xerces.internal.jaxp, Java Platform API Specification, version 1.7 

TransformerFactory class name:  com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl 
TransformerFactory class loader:  null 
transformerFactory class package:  package com.sun.org.apache.xalan.internal.xsltc.trax, Java Platform API Specification, version 1.7 

Transformer class name:    com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl 
Transformer class loader:   null 
Transformer class package:   package com.sun.org.apache.xerces.internal.jaxp, Java Platform API Specification, version 1.7 

而這裏的日誌,錯誤的輸出:

DocumentBuilderFactory class name:  org.apache.xerces.jaxp.DocumentBuilderFactoryImpl 
DocumentBuilderFactory class loader:  [email protected] 
DocumentBuilderFactory class package:  package org.apache.xerces.jaxp 

DocumentBuilder class name:    org.apache.xerces.jaxp.DocumentBuilderImpl 
DocumentBuilder class loader:   [email protected] 
DocumentBuilder class package:  package org.apache.xerces.jaxp 

TransformerFactory class name:  org.apache.xalan.processor.TransformerFactoryImpl 
TransformerFactory class loader:  [email protected] 
transformerFactory class package:  package org.apache.xalan.processor 

Transformer class name:    org.apache.xalan.transformer.TransformerIdentityImpl 
Transformer class loader:   [email protected] 
Transformer class package:   package org.apache.xerces.jaxp 

我想告訴第二臺機器的行爲類似於第一個,但我不熟悉cloassloaders如何工作。有人可以給我詳細的信息:

1)爲什麼有差異,在這種情況下類加載意味着什麼? 2)如何修改機器#2的默認行爲以使用與機器#1相同的東西?

回答

1

這可能是錯誤的方法。來自Apache的Xerces和Xalan版本通常比JDK中的版本更可靠,更健壯,並且符合標準。我會嘗試將所有內容都轉移到Apache版本,並解決爲什麼你的代碼在這些情況下給出了錯誤的結果,並對其進行修復。我們需要詳細瞭解您認爲哪些代碼給出了錯誤的結果,告訴您哪些產品實際上是按照規範行事,哪些不是。根據規格選擇合適的產品比選擇恰好按你想要的產品更好。

您可以通過多種方式控制JAXP加載的版本:更改類路徑上的內容,設置Java系統屬性或顯式加載選定的版本。如果您查看Javadoc以獲取像DocumentBuilderFactory和TransformerFactory這樣的類,它會給出一個非常詳細的解釋。

+0

我完全同意你的說法,除了在這種特殊情況下,我認爲官方的xml命名空間規範說「沒有命名空間」應該被視爲「命名空間==空字符串」,這是標準JDK版本的變換器,但是Apache版本不。所以我只能假設這個Apache變壓器可能是錯誤的。話雖如此,我認爲它適合我使用apache並通過改變我的代碼來「修復」他們的「bug」,以達到相同的結果。 – user1884155 2014-09-04 12:28:48

+0

我想更詳細地瞭解您認爲哪些操作會出錯。你甚至沒有告訴我們這是一個DOM操作還是一個XSLT操作。 「官方XML命名空間規範」不包括DOM或XSLT,所以我不確定它的相關性。 – 2014-09-04 14:04:30

+0

我在Document對象中有一個名稱空間== null的元素。我使用transform類將此元素轉換爲字符串。良好的轉換:將元素轉換爲具有等於空字符串的名稱空間。錯誤轉換:忽略該元素的名稱空間。 – user1884155 2014-09-04 14:07:10