web-dev-qa-db-fra.com

Normalisation dans le DOM avec Java - comment ça marche?

J'ai vu la ligne ci-dessous dans le code pour un analyseur DOM à ce tutoriel .

doc.getDocumentElement().normalize();

Pourquoi faisons-nous cette normalisation?
J'ai lu le docs mais je ne comprenais pas un mot.

Place tous les nœuds de texte dans toute la profondeur de la sous-arborescence sous ce nœud.

D'accord, alors quelqu'un peut-il me montrer (de préférence avec une photo) à quoi ressemble cet arbre?

Quelqu'un peut-il m'expliquer pourquoi la normalisation est nécessaire?
Que se passe-t-il si nous ne normalisons pas?

226
Apple Grinder

Le reste de la phrase est:

où seule la structure (par exemple, des éléments, des commentaires, des instructions de traitement, des sections CDATA et des références d'entité) sépare les nœuds de texte, c'est-à-dire qu'il n'y a ni nœuds de texte adjacents ni nœuds de texte vides.

Cela signifie fondamentalement que l'élément XML suivant

<foo>hello 
wor
ld</foo>

pourrait être représenté comme ceci dans un noeud dénormalisé:

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

Une fois normalisé, le nœud ressemblera à ceci

Element foo
    Text node: "Hello world"

Et il en va de même pour les attributs: <foo bar="Hello world"/>, les commentaires, etc.

350
JB Nizet

En guise d'extension de la réponse de @ JBNizet pour les utilisateurs plus techniques, voici à quoi ressemble l'implémentation de l'interface org.w3c.dom.Node dans com.Sun.org.Apache.xerces.internal.dom.ParentNode, qui vous donne une idée de son fonctionnement réel.

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);
}

Il traverse tous les nœuds de manière récursive et appelle kid.normalize()
Ce mécanisme est annulé dans 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);
 } 

J'espère que cela vous fait gagner du temps.

6
Matas Vaitkevicius

En termes simples, la normalisation est la réduction des redondances.
Exemples de redondances:
a) espaces blancs en dehors des balises racine/document (... <document> </ document> ...)
b) des espaces entre les balises de début (<...>) et les balises de fin (</ ...>)
c) espaces entre les attributs et leurs valeurs (c'est-à-dire espaces entre nom de la clé et = ")
d) déclarations d'espace de noms superflues
e) sauts de ligne/espaces dans les textes d'attributs et de balises
f) commentaires etc ...

6
AVA