问题
我在this tutorial的DOM解析器的代码中看到了下面这一行。
doc.getDocumentElement().normalize();
为什么我们这样做正常化?
我读了docs但我听不懂。
将所有Text节点放在此Node下面的子树的完整深度中
好吧,那么有人可以告诉我(最好是带图片)这棵树的样子吗?
任何人都可以解释为什么需要正常化吗?
如果我们不规范化会发生什么?
#1 热门回答(316 赞)
其余的句子是:
其中只有结构(例如,元素,注释,处理指令,CDATA部分和实体引用)将Text节点分开,即,既没有相邻的Text节点也没有空的Text节点。
这基本上意味着以下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"/>
,评论等。
#2 热门回答(5 赞)
简单来说,规范化就是减少冗余。
Redundancies示例:
a)根/文档标记之外的空格(... <document> </ document> ...)
b)开始标记(<...>)和结束标记(</ ...>)中的空格
c)属性与其值之间的空格(即之间的空格,密钥名称和**="**")
d)多余的名称空间声明
e)属性和标签文本中的换行符/空格
f)评论等......
#3 热门回答(4 赞)
作为@ JBNizet对更多技术用户的回答的延伸,这里的内容是842515344接口的实现,它可以让你了解它实际上是如何工作的。
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);
}
它以递归方式遍历所有节点并调用kid.normalize()
这种机制在363171615中被覆盖
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);
}
希望这能为你节省一些时间。