使用Java在DOM解析中进行规范化-它如何工作?


240

本教程中,我在DOM解析器的代码中看到以下行。

doc.getDocumentElement().normalize();

我们为什么要进行这种归一化?
我阅读了文档,但我听不懂一个字。

将所有Text节点置于该节点下子树的完整深度

好吧,那么有人可以告诉我(最好是附照片)这棵树是什么样的吗?

谁能解释我为什么需要规范化?
如果我们不规范会怎样?


不管您有什么问题,请阅读示例中的注释:“ DOM解析器速度很慢,并且在加载包含大量数据的XML文档时会占用大量内存。请考虑使用SAX解析器作为解决方案,SAX更快比DOM占用更少的内存。”
wulfgarpro 2012年

3
@ wulfgar.pro-我明白你的意思。但是,我想了解我在问题中提出的内容。我还将很快进行SAX解析。
Apple Grinder 2012年

在google中搜索“ normalize xml”会给出一些有用的结果。它看起来类似于数据库中的规范化。
苹果研磨机

2
@EJP-嗯...它仍然不清楚,因为我不了解xml的深度,而且我只读了一些介绍性页面。顺便说一句,不要误会我的意思,您确实做到了文档作者的所作所为-使用复杂的单词而不是简单的英语(纯朴的派克员工=易于理解)。首先说简单的话,后来用行话对我来说更好。
苹果研磨机

7
在撰写本文时,所引用的网站正在引用此SO帖子。我的大脑只是抛出了一个依赖错误。
13

Answers:


366

句子的其余部分是:

其中只有结构(例如元素,注释,处理指令,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"/>,注释等也是如此。


2
啊哈!现在更清楚了。我不了解数据结构(???)和节点。但是我快速浏览了树结构,并且我猜想一台计算机可能会按照您建议的方式存储“ hello world”。那正确吗 ?
苹果研磨机

9
您需要学习有关DOM的基础知识。是的,DOM将XML文档表示为树。在树中,您有一个具有子节点的根节点,每个子节点也都具有子节点,等等。这就是一棵树。元素是一种节点,而文本节点是另一种节点。
JB Nizet

7
感谢JB Nizet。告诉你一些方向后,我很难过。
苹果研磨机

2
@ user2043553,换行实际上就是关键所在。没有换行符,您将看不到区别。如果您不应该了解以下内容:规范化会“更正” XML,因此将一个标签解释为一个元素。如果您不这样做,则可能会将这些非常新的换行符解释为相同类型(分别在同一标记中)的多个元素之间的分隔符。
堆积

1
@Stacky,在该示例中有两个新行,在示例中进行规范化后不会显示它们,这可能使人们认为不再存在。结果显示的带有换行符的文本节点如下所示:“ Hello \ nwor \ nld”规范化不会删除换行符。
基督教徒

10

简单来说,归一化是减少冗余。
:冗余实例
一)的白色空间的根/文档标签外(... <文件> </文件> ...
b)中开始标签内的白空间(< ... >)和结束标记(</ ... >)
c)属性及其值之间的空格(即键名=“之间的空格)
d)多余的名称空间声明
e)属性和标签文本中的换行符/空格
f)注释等...


7

作为@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);
 } 

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.