Нормализация в DOM разборе с java-как это работает?
Я видел строку ниже в коде для парсера DOM в в этом уроке.
doc.getDocumentElement().normalize();
почему мы делаем эту нормализацию ?
Я прочитал docs но я не мог понять ни слова.
помещает все текстовые узлы в полную глубину поддерева под этим узлом
Хорошо, тогда может кто-нибудь показать мне (желательно с картинкой), как выглядит это дерево ?
может кто-нибудь объяснить мне, почему нормализация нужна?
Что произойдет, если мы не нормализовать ?
3 ответа:
остальная часть предложения:
где только структура (например, элементы, комментарии, инструкции по обработке, разделы 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"/>
, замечания и т. д.
проще говоря, нормализация-это сокращение избыточности.
примеры избыточности:
a) пробелы вне тегов корня / документа (...документ>...)
b) пробелы в теге start (...>) и закрывающего тега (...>)
c) пробелы между атрибутами и их значениями (т. е. пробелы между введите имя и =")
d) избыточное пространство имен декларации
e) разрывы строк/пробелы в текстах атрибутов и тегов
е) замечания и т. д...
в качестве расширения к ответу @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); }
надеюсь, что это экономит ваше время.