나는 XML을 처리하기가 다소 번거 롭다는 것을 항상 발견했다. 나는 XML 파서를 구현하는 것에 대해 이야기하는 것이 아니라 노드별로 XML을 처리하는 SAX 파서와 같은 기존 스트림 기반 파서를 사용 하는 것에 대해 이야기하고 있습니다.
예, 이러한 파서에 대한 다양한 API를 배우는 것은 정말 쉽지만 XML을 처리하는 코드를 볼 때마다 항상 다소 복잡하다는 것을 알게됩니다. 근본적인 문제는 XML 문서가 논리적으로 개별 노드로 분리되어 있지만 데이터 유형 과 속성이 종종 여러 레벨의 중첩에 의해 실제 데이터와 분리되는 것 같습니다. 따라서 특정 노드를 개별적으로 처리 할 때는 현재 위치 와 다음에 수행 할 작업 을 결정하기 위해 많은 추가 상태를 유지 해야합니다.
예를 들어, 일반적인 XML 문서의 스 니펫이 제공된 경우 :
<book>
<title>Blah blah</title>
<author>Blah blah</author>
<price>15 USD</price>
</book>
... 책 제목이 포함 된 텍스트 노드를 발견 한 시점을 어떻게 알 수 있습니까? 우리가 호출 할 때마다 XML 문서의 다음 노드를 제공하는 반복자처럼 작동하는 간단한 XML 파서가 있다고 가정하십시오 XMLParser.getNextNode()
. 필자는 다음과 같은 코드를 작성해야합니다.
boolean insideBookNode = false;
boolean insideTitleNode = false;
while (!XMLParser.finished())
{
....
XMLNode n = XMLParser.getNextNode();
if (n.type() == XMLTextNode)
{
if (insideBookNode && insideTitleNode)
{
// We have a book title, so do something with it
}
}
else
{
if (n.type() == XMLStartTag)
{
if (n.name().equals("book")) insideBookNode = true
else if (n.name().equals("title")) insideTitleNode = true;
}
else if (n.type() == XMLEndTag)
{
if (n.name().equals("book")) insideBookNode = false;
else if (n.name().equals("title")) insideTitleNode = false;
}
}
}
기본적으로 XML 처리는 이전에 찾은 부모 노드를 나타내는 데 사용되는 많은 상태 변수와 함께 거대한 상태 머신 기반 루프로 빠르게 전환됩니다. 그렇지 않으면 중첩 된 모든 태그를 추적하기 위해 스택 객체를 유지 관리해야합니다. 이로 인해 오류가 발생하기 쉽고 유지 관리가 어려워집니다.
다시 말하지만, 우리가 관심있는 데이터가 개별 노드와 직접적으로 연관되어 있지 않은 것 같습니다. 물론 다음과 같이 XML을 작성하면 가능할 수 있습니다.
<book title="Blah blah" author="blah blah" price="15 USD" />
... 실제로 XML이 사용되는 방식은 거의 없습니다. 대부분 우리는 부모 노드의 자식으로 텍스트 노드를 가지고 있으며 텍스트 노드가 무엇을 의미하는지 결정하기 위해 부모 노드를 추적해야합니다.
그래서 ... 내가 뭔가 잘못하고 있습니까? 더 좋은 방법이 있습니까? XML 스트림 기반 구문 분석기를 사용하는 것이 어느 시점에서 너무 번거로워서 본격적인 DOM 구문 분석기가 필요합니까? 스트림 기반 파서를 사용하여 XML을 처리 할 때 어떤 종류의 관용구가 사용되는지 다른 프로그래머들로부터 듣고 싶습니다. 스트림 기반 XML 구문 분석이 항상 거대한 상태 머신으로 전환되어야합니까?