2010-08-04 94 views
2

我目前正在修改一段代碼,我想知道如果XML格式化(製表符和間距)將影響它被分析到DocumentBuilderFactory類的方式。Xml文檔使用DocumentBuilderFactory的DOM對象

實際上,問題是......我可以傳遞一個沒有間距的大長字符串到DocumentBuilderFactory中,還是需要以某種方式進行格式化?

在此先感謝,下面包含的是來自Oracles網站的類定義。

類的DocumentBuilderFactory

「定義工廠API,使應用程序能夠獲得從XML文檔生成DOM對象樹的解析器。」

回答

1

它不應該作爲長期影響解析器的能力爲字符串是有效 XML。製表符和換行符被解析器剝離或忽略,並且真正用於人類讀者的美學。

請注意,您將不得不將輸入流(例如StringBufferInputStream)傳遞給DocumentBuilder,因爲字符串版本的解析假定它是XML的URI。

+0

感謝的信息,在末尾位,好知道 – Candyfloss 2010-08-04 10:09:57

+3

這是不正確的。我測試過了。使用換行符和無換行符的xml字符串構建DOM對象是不同的! – sarahTheButterFly 2010-09-23 05:25:07

0

對於XML-String的格式應該沒有任何影響,但我可以記住一個奇怪的問題,因爲我將一個長字符串傳遞給XML解析器。由於它被寫在一條長長的行中,因此paser無法解析XML文件。

如果你插入換行符,那種換行不會長於1000字節,可能會更好。

但不幸的是,我做neigther記住爲什麼發生錯誤,以及我採取了哪個解析器。

+0

我認爲XML解析器忽略換行。它是DocumentBuilder構建不同的DOM對象依賴於帶有或不帶有換行的xml字符串 – sarahTheButterFly 2010-09-23 23:28:59

+0

您是對的,但我記得XML-Api或Lib中的一個Bug,由於該特殊實現,無法構建DOM每行只能讀取x個字節。 – 2010-09-24 09:18:52

1

DocumentBuilder使用換行符和xml字符串爲不帶換行符的xml字符串構建不同的DOM對象。下面是我測試的代碼:

StringBuilder sb = new StringBuilder(); 
sb.append("<root>").append(newlineChar).append("<A>").append("</A>").append(newlineChar).append("<B>tagB").append("</B>").append("</root>"); 

DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); 

InputStream xmlInput = new ByteArrayInputStream(sb.toString().getBytes()); 
Element documentRoot = builder.parse(xmlInput).getDocumentElement(); 

NodeList nodes = documentRoot.getChildNodes(); 

System.out.println("How many children does the root have? => "nodes.getLength()); 

for(int index = 0; index < nodes.getLength(); index++){ 
    System.out.println(nodes.item(index).getLocalName()); 
} 

輸出:
How many children does the root have? => 4
null
A
null
B

但是,如果新newlineChar從StringBuilder的刪除, 的ouptput是:
How many children does the root have? => 2
A
B

這演示由DocumentBuilder生成的DOM對象是不同的。

3

這些文件將有所不同。選項卡和新行將被轉換爲文本節點。您可以使用以下方法上的DocumentBuilderFactory消除這些:

但爲了使其正常工作,你必須設置你的DOM解析器來驗證對一個DTD或XML Schema的內容。

另外,您可以使用類似下面的編程方式刪除自己多餘的空白:

public static void removeEmptyTextNodes(Node node) { 
    NodeList nodeList = node.getChildNodes(); 
    Node childNode; 
    for (int x = nodeList.getLength() - 1; x >= 0; x--) { 
     childNode = nodeList.item(x); 
     if (childNode.getNodeType() == Node.TEXT_NODE) { 
      if (childNode.getNodeValue().trim().equals("")) { 
       node.removeChild(childNode); 
      } 
     } else if (childNode.getNodeType() == Node.ELEMENT_NODE) { 
      removeEmptyTextNodes(childNode); 
     } 
    } 
}