Java를 사용한 DOM 구문 분석의 정규화 - 어떻게 작동합니까?
이 튜토리얼에서 DOM 파서의 코드로 아래 행을 보았습니다.
doc.getDocumentElement().normalize();
이 정규화를 실시하는 이유는 무엇입니까?
나는 그 문서를 읽었지만 한 마디도 알아들을 수 없었다.
모든 텍스트 노드를 이 노드 아래 하위 트리의 전체 깊이에 배치합니다.
좋아요, 그럼 누가 이 트리가 어떻게 생겼는지 보여줄 수 있나요?
왜 정상화가 필요한지 설명해줄 사람?
정상화하지 않으면 어떻게 되나요?
나머지 문장은 다음과 같습니다.
여기서 구조(예: 요소, 주석, 처리 명령, 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) 루트/스위치 태그(...) 외부에 공백이 있습니다.</filename> </filename>...)
b) 시작 태그(<...>)와 종료 태그(<...>) 내의 공백.>)
c) 속성과 값 사이의 공백(키 이름과 =" 사이의 공백)
d) 불필요한 네임스페이스 선언
e) 속성 및 태그 텍스트의 줄 바꿈/공백
f) 코멘트 등...
더 많은 기술 사용자에 대한 @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);
}
이것으로 시간을 절약하시길 바랍니다.
언급URL : https://stackoverflow.com/questions/13786607/normalization-in-dom-parsing-with-java-how-does-it-work
'source' 카테고리의 다른 글
| CMake 아래에 있는 여러 디렉토리 (0) | 2022.07.30 |
|---|---|
| Java에서 주석의 사용방법과 사용처 (0) | 2022.07.30 |
| Vue.js / Larabel - 로그아웃을 올바르게 처리 (0) | 2022.07.30 |
| Java 애플리케이션 내부에서 VM 인수를 가져오려면 어떻게 해야 합니까? (0) | 2022.07.30 |
| vue-cli-service build 명령을 사용하여 자산을 복사하는 방법 (0) | 2022.07.30 |