doc.getDocumentElement().normalize();
为什么要进行规范化? 将所有Text节点放置在此Node下方子树的完整深度中
好向我展示(最好带有图片)这棵树是什么样的?
谁能解释我为什么需要规范化? />
#1 楼
句子的其余部分是:其中只有结构(例如,元素,注释,处理指令,CDATA部分和实体引用)分隔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"/>
,注释等。评论
啊哈!现在更清楚了。我不了解数据结构(???)和节点。但是我快速浏览了树的结构,并且我猜想计算机可能会按照您建议的方式存储“ hello world”。是对的吗 ?
–苹果研磨机
2012年12月9日在13:12
您需要学习有关DOM的基础知识。是的,DOM将XML文档表示为树。在树中,您有一个具有子节点的根节点,每个子节点也都具有子节点,等等。这就是一棵树。元素是一种节点,而文本节点是另一种节点。
– JB Nizet
2012年12月9日在13:20
感谢JB Nizet。无法告诉您在获得指导后我有多放心。
–苹果研磨机
2012年12月9日下午13:26
@ user2043553,换行实际上就是关键所在。没有换行符,您将看不到区别。如果您不应该了解以下内容:标准化会“更正” XML,因此将一个标签解释为一个元素。如果您不这样做,则可能会将这些非常新的换行符解释为相同类型(分别在同一标记中)的多个元素之间的分隔符。
–堆叠
2014-10-23 15:59
@Stacky,在该示例中有两个新行,在示例中进行归一化后不会显示它们,这可能使人们认为不再存在。结果显示的带有换行符的文本节点如下所示:“ Hello \ nwor \ nld”规范化不会删除换行符。
–基督徒
15年3月22日在19:09
#2 楼
简单来说,归一化是减少冗余。冗余示例:a)根/文档标签(...
之外的空白b)起始标签(<... >)和结束标记( ...>)
c)属性及其值之间的空格(即键名和=“之间的空格)
f)注释等...
#3 楼
作为对@JBNizet针对更多技术用户的答案的扩展,以下是org.w3c.dom.Node
中com.sun.org.apache.xerces.internal.dom.ParentNode
接口的实现,它使您了解其实际工作方式。 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()
此机制在
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);
}
< br希望这可以节省您一些时间。
评论
不管您有什么问题,请阅读示例中的注释:“ DOM解析器很慢,并且在加载包含大量数据的XML文档时会占用大量内存。请考虑使用SAX解析器作为解决方案,SAX更快比DOM占用更少的内存。”@ wulfgar.pro-我明白你的意思。但是,我想了解我在问题中提出的内容。我还将很快进行SAX解析。
在google上搜索“ normalize xml”会得到一些有用的结果。它看起来类似于数据库中的规范化。
@EJP-嗯...它仍然不清楚,因为我不了解xml的深度,而且我只读了一些介绍性页面。顺便说一句,不要误会我的意思,您确实做到了文档作者的所作所为-使用复杂的单词而不是简单的英语(纯朴的派克员工=易于理解)。首先说简单的话,后来用行话对我来说更好。
在撰写本文时,所引用的网站正在引用此SO帖子。我的大脑刚刚抛出了依赖项错误。