2010-07-20 2 views
2

에서 XML 노드를 계산하는 가장 효율적인 방법은 무엇이며, 분명히 나는 ​​한 번에 전체 파일을 구문 분석 할 수 없습니다 부품을 파싱하고 그들과 함께 무엇이든하십시오.내가 1-2gb까지 거대한 XML 파일이 자바

특정 노드의 수는 어떻게 계산합니까? 따라서 파일을 분할하는 데 필요한 부품 수를 추적 할 수 있습니다. 이 작업을 수행하는 더 좋은 방법이 있습니까? 나는 모든 제안은 감사에 열려있어

질문 업데이트 :

그럼 내가 STAX를 사용 했, 어쩌면 내가 그것을 사용하고 논리가 잘못, 나는 각각 다음 파일을 구문 분석하고 있습니다 노드 노드 값을 가져 와서 문자열 작성기 안에 저장합니다. 그런 다음 다른 방법으로 나는 물결 모양의 stringbuilder로 가서 출력을 편집합니다. 그런 다음 해당 출력을 파일에 씁니다. 이런 식으로 10000 개를 초과 할 수는 없습니다. 여기

내가 얻을 예외 :
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space 
     at com.sun.org.apache.xerces.internal.util.NamespaceSupport.<init>(Unkno 
wn Source) 
     at com.sun.xml.internal.stream.events.XMLEventAllocatorImpl.setNamespace 
Context(Unknown Source) 
     at com.sun.xml.internal.stream.events.XMLEventAllocatorImpl.getXMLEvent(
Unknown Source) 
     at com.sun.xml.internal.stream.events.XMLEventAllocatorImpl.allocate(Unk 
nown Source) 
     at com.sun.xml.internal.stream.XMLEventReaderImpl.nextEvent(Unknown Sour 
ce) 
     at com.sun.org.apache.xalan.internal.xsltc.trax.StAXEvent2SAX.bridge(Unk 
nown Source) 
     at com.sun.org.apache.xalan.internal.xsltc.trax.StAXEvent2SAX.parse(Unkn 
own Source) 
     at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transfor 
mIdentity(Unknown Source) 
     at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transfor 
m(Unknown Source) 
     at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transfor 
m(Unknown Source) 

이 사실 나는 내 모든 접근 방식이 잘못 생각, 내가 실제로 CSV 샘플로 XML 파일을 변환 할 노력하고있어. 여기가 내가 지금까지 그것을 할 방법은 다음과 같습니다

  • 얻을 각 요소 노드 텍스트 노드 값에 대한 읽기/구문 분석 XML 파일
  • 열기 스트림은 n 개의 노드 (임시) 파일에 쓸 다음 씻고 가까운 스트림
  • 는 그런 다음 적절한 CSV 출력을 생성
+0

"이처럼 10000 개가 넘는 개체가 아닙니다"라는 것은 무엇을 의미합니까? 잡은 오류 또는 예외는 무엇입니까? –

+0

STAX API는 많은 메모리를 사용하지 않지만 STAX가 반복을 수행 할 때 자신의 프로그램이 많은 양의 데이터를 저장하고 있다면 STAX의 오류가 아닙니다. 다른 XML API를 선택하지 않고 자신의 메모리 관리를 정렬해야합니다. – skaffman

+0

왜 값을 stringbuilder에 저장합니까? 독립형 노드 값으로 작업 할 수없는 이유는 무엇입니까? – josefx

답변

4

SAX 또는 STAX API가 최선의 방법입니다. 그들은 한 번에 모든 것을 파싱하지 않고 한 번에 하나의 노드를 가져 와서 앱이 처리하도록합니다. 임의로 큰 문서에 유용합니다.

SAX는 이전 API이며 푸시 모델에서 작동하며 STAX는 최신이며 끌어 오기 구문 분석기이므로 사용하기가 더 쉽지만 요구 사항에 따라 어느 쪽이라도 괜찮습니다.

는 STAX 구문 분석을 시작하는 this tutorial를 참조하십시오.

+0

+1을 사용하면 StaX (끌어 오기)가 SAX보다 사용하기 쉽습니다. – naikus

0

당신은 이러한 이벤트 기반 파서를 사용하여 더 나을 것 csv 파일에 기록하는 온도에서 읽을 다른 스트림, 공유지 스트립 유틸을 사용하고 다른 물건을 엽니 다 SAX

1

나는 당신이 DOM, 그래서 SAX 또는 StAX가 좋은 선택해야을 만들지 않도록하려는 생각합니다. SAX와

은 흥미로운 요소가 발견되면 단지 카운터를 증가 simlpe의 컨텐츠 핸들러를 구현합니다.

2

당신은 이것에 대한 StAX 같은 스트리밍 파서를 사용할 수 있습니다. 이렇게하면 메모리에있는 전체 파일을 한 번에 읽을 필요가 없습니다. 이 메모리는 현재 비트를 보유하고 있으므로, 그것은 스트리밍 것 :

1

SAX 사용하면 파일을 분할 할 필요가 없습니다. 계산을 수행하는 ContentHandler를 작성하는 것은 매우 쉽습니다. 그리고 그것은 매우 빠릅니다 (제 경험상, 파일을 읽는 것만 큼 빠르게).

0

파일을 분할하는 것은 갈 길이 없다고 생각합니다. xml 파일을 스트림으로 처리하고 DOM API가 아닌 SAX API를 사용하는 것이 좋습니다.

더 나은 방법은 XQuery를 사용하여 요청을 처리하는 것입니다.

색슨 색소폰은 색소폰을 사용하는 자바/.Net 구현으로, 대용량 파일에서도 놀랍도록 빠릅니다. 버전은 MPL 오픈 소스 라이센스하에 있습니다.

java -cp saxon9he.jar net.sf.saxon.Query -qs:"count(doc('/path/to/your/doc/doc.xml')//YouTagToCount)" 
1

그럼 난 STAX를 사용 했, 어쩌면 내가 그것을 사용하고 논리가 잘못이다, 내가 '각 노드에 대해 다음 파일을 구문 분석하고 있습니다 : 여기

조금 예입니다 노드 값을 가져 와서 문자열 작성기에 저장합니다. 그런 다음 다른 방법으로 나는 물결 모양의 stringbuilder로 가서 출력을 편집합니다. 그런 다음 해당 출력을 파일에 씁니다. 이런 식으로 10000 개를 초과 할 수는 없습니다.

이 설명을 통해 나는 네가 사용하는 논리가 잘못되었다고 말하고 싶습니다. 당신은 너무 많은 것을 기억하고 있습니다.

전체 파일을 구문 분석하고 모든 노드 값을 무언가에 저장 한 다음 결과를 처리하는 대신 각 노드를 명중시키면서 처리하고 파싱하는 동안 출력해야합니다.

실제 달성하려는 내용과 입력 XML 및 모양이 무엇이든간에 더 자세한 내용을 살펴보면 능률화를 도울 수 있습니다.

0

확장 된 vtd-xml을 사용하면 메모리 매핑을 지원하므로 효율적으로 문서를 메모리에로드 할 수 있습니다. DOM과 비교할 때 메모리 사용은 엄청난 규모로 폭발하지 않습니다. 그리고 xpath를 사용하여 노드 수를 매우 쉽게 계산할 수 있습니다.

관련 문제