用JavaparsingDOM规范化 – 它是如何工作的?

在本教程中,我在下面的代码中看到了DOMparsing器的代码。

doc.getDocumentElement().normalize(); 

为什么我们要做这个正常化?
我阅读文档,但我不明白一个字。

将此节点下的子树的全部深度放置为所有文本节点

好的,那么有人能告诉我(最好是有图片)这棵树是什么样的?

任何人都可以解释为什么需要规范化?
如果我们没有正常化会发生什么?

其余的句子是:

其中只有结构(例如元素,注释,处理指令,CDATA节和实体引用)将文本节点分开,即既没有相邻的文本节点,也没有空的文本节点。

这基本上意味着下面的XML元素

 <foo>hello wor ld</foo> 

可以在非规范化的节点中像这样表示:

 Element foo Text node: "" Text node: "Hello " Text node: "wor" Text node: "ld" 

标准化后,节点将如下所示

 Element foo Text node: "Hello world" 

而属性也是如此: <foo bar="Hello world"/> ,comments等

作为@ JBNizet针对更多技术用户的答案的扩展,这里是com.sun.org.apache.xerces.internal.dom.ParentNodeorg.w3c.dom.Node接口的实现,它为您提供了实际的工作方式。

 public void normalize() { // No need to normalize if already normalized. if (isNormalized()) { return; } if (needsSyncChildren()) { synchronizeChildren(); } ChildNode kid; for (kid = firstChild; kid != null; kid = kid.nextSibling) { kid.normalize(); } isNormalized(true); } 

它recursion遍历所有节点并调用kid.normalize()
这个机制在org.apache.xerces.dom.ElementImpl被覆盖

 public void normalize() { // No need to normalize if already normalized. if (isNormalized()) { return; } if (needsSyncChildren()) { synchronizeChildren(); } ChildNode kid, next; for (kid = firstChild; kid != null; kid = next) { next = kid.nextSibling; // If kid is a text node, we need to check for one of two // conditions: // 1) There is an adjacent text node // 2) There is no adjacent text node, but kid is // an empty text node. if ( kid.getNodeType() == Node.TEXT_NODE ) { // If an adjacent text node, merge it with kid if ( next!=null && next.getNodeType() == Node.TEXT_NODE ) { ((Text)kid).appendData(next.getNodeValue()); removeChild( next ); next = kid; // Don't advance; there might be another. } else { // If kid is empty, remove it if ( kid.getNodeValue() == null || kid.getNodeValue().length() == 0 ) { removeChild( kid ); } } } // Otherwise it might be an Element, which is handled recursively else if (kid.getNodeType() == Node.ELEMENT_NODE) { kid.normalize(); } } // We must also normalize all of the attributes if ( attributes!=null ) { for( int i=0; i<attributes.getLength(); ++i ) { Node attr = attributes.item(i); attr.normalize(); } } // changed() will have occurred when the removeChild() was done, // so does not have to be reissued. isNormalized(true); } 

希望这可以为你节省一些时间。

简单地说,规范化就是减less冗余。
冗余示例:
a)根/文档标签之外的空白(… <document> </ document> …)
b)开始标记(<…>)和结束标记(</ …>)内的空格
c)属性和值之间的空格(即键名=之间的空格)
d)多余的名称空间声明
e)属性和标签文本中的换行符/空格
f)评论等