는 방법은 분할 XML 문서는 분으로(또는,더 나은,n 개)?

StackOverflow https://stackoverflow.com/questions/7846

  •  08-06-2019
  •  | 
  •  

문제

내가 사용하고 싶어하는 내가 잘 알 Java,C#,Ruby,PHP,C/C++,지만 예제에서는 어떤 언어 또는 의사보다 더 많은 환영받습니다.

는 가장 좋은 방법은 무엇입의 분할은 대규모 XML 문서를 작은 부분으로 여전히 유효한 XML?내 목적을 위해 내가 필요로 분할하는 대략 분의 또는분만을 위해서 제공하는 예는 분할,그들 n 로 구성 요소는 것이 좋습니다.

도움이 되었습니까?

해결책

물론 당신은 항상추출물이 최고 수준 요소(지 세분 당신은 당신).C#에서는 다음을 사용할 수 있습니다 XmlDocument 클래스입니다.는 경우,예를 들어,당신 XML 파일은 아래와 같습니다.

<Document>
  <Piece>
     Some text
  </Piece>
  <Piece>
     Some other text
  </Piece>
</Document>

다음 코드를 사용하여 다음과 같이 추출하려는 모든 조각의:

XmlDocument doc = new XmlDocument();
doc.Load("<path to xml file>");
XmlNodeList nl = doc.GetElementsByTagName("Piece");
foreach (XmlNode n in nl)
{
    // Do something with each Piece node
}

일단 당신이 가지고 노드 작업을 수행할 수 있습니다 그들의 코드,또는 전송할 수 있습 전체 텍스트 노드의 그것의 자신의 XML 문서에 따라 행동하는 것처럼 독립적인 조각의 XML(를 포함하여 다시 저장하는 디스크,etc.).

다른 팁

분석 XML 문서를 사용하여 돔하지 않는 규모입니다.

그루비-스크립트를 사용하고 택스(스트리밍 API for XML)분 XML 문서를 사 톱 레벨 요소(을 공유하는 동 QName 으로 첫 번째 아동의 근본 문서).그것은 매우 빠르고,손잡이를 임의로 대량의 문서와 매우 유용하고 싶을 때 분할 큰 배치 파일 작은 조각으로.

이 필요합 그루비에서 Java6 나 StAX API 를 구현 등 Woodstox 클래스 경로에

import javax.xml.stream.*

pieces = 5
input = "input.xml"
output = "output_%04d.xml"
eventFactory = XMLEventFactory.newInstance()
fileNumber = elementCount = 0

def createEventReader() {
    reader = XMLInputFactory.newInstance().createXMLEventReader(new FileInputStream(input))
    start = reader.next()
    root = reader.nextTag()
    firstChild = reader.nextTag()
    return reader
}

def createNextEventWriter () {
    println "Writing to '${filename = String.format(output, ++fileNumber)}'"
    writer = XMLOutputFactory.newInstance().createXMLEventWriter(new FileOutputStream(filename), start.characterEncodingScheme)
    writer.add(start)
    writer.add(root)
    return writer
}

elements = createEventReader().findAll { it.startElement && it.name == firstChild.name }.size()
println "Splitting ${elements} <${firstChild.name.localPart}> elements into ${pieces} pieces"
chunkSize = elements / pieces
writer = createNextEventWriter()
writer.add(firstChild)
createEventReader().each { 
    if (it.startElement && it.name == firstChild.name) {
        if (++elementCount > chunkSize) {
            writer.add(eventFactory.createEndDocument())
            writer.flush()
            writer = createNextEventWriter()
            elementCount = 0
        }
    }
    writer.add(it)
}
writer.flush()

로 DannySmurf 에 여기에,그것은 모두의 구조에 대한 xml 문서입니다.
당신이 두 거대한"최고 수준"태그에,그것은 매우 열심히 할 수 있을 분할하에 그것을 만드는 방식으로 가능한 모두 병 함께 다시고 그것을 읽는 조각으로 유효한 것으로 xml.

주어진 문서의 많은 별도의 조각 같은 것들에 DannySmurfs 를 들어,그것은 매우 쉽습니다.
일부 거친 코드에 의사 C#:

int nrOfPieces = 5;
XmlDocument xmlOriginal = some input parameter..

// construct the list we need, and fill it with XmlDocuments..
var xmlList = new List<XmlDocument>();
for (int i = 0; i < nrOfPieces ; i++)
{
    var xmlDoc = new XmlDocument();
    xmlDoc.ChildNodes.Add(new XmlNode(xmlOriginal.FistNode.Name));
    xmlList.Add(xmlDoc);
}

var nodeList = xmlOriginal.GetElementsByTagName("Piece")M
// Copy the nodes from the original into the pieces..
for (int i = 0; i < nodeList .Count; i++)
{
    var xmlDoc = xmlList[i % nrOfPieces];
    var nodeToCopy = nodeList[i].Clone();
    xmlDoc.FirstNode.ChildNodes.Add(nodeToCopy);
}

이것은 당신에게 제공 n 문서와 함께 올바른 xml 과 가능성을 병합하는 다시 함께합니다.
그러나 다시는 그에 따라 달라집 xml 파일입니다.

이상의 의견 보다는 대답만,없을 것:

XmlDocument doc = new XmlDocument();
doc.Load("path");

전체 파일에 한 번?다만 생각해야 하는 점을 올 이후의 모습에서 도마의 질문에 그에 대한 우려를 읽고 큰 파일을 원하는 휴식하는 프로세스입니다.

그것을 읽는 전체 파일에 한 번.내 경험에 의하면,하지만,당신은 독서 파일을 처리한다(즉,그것)그리고 계속 작업,XmlDocument 갈을 통해 그것의 생성//읽기를 수집하기 그렇게 신속하게 할 가능성이 문제가 되지 않습니다.

물론,에 따라 달라지는 것이"큰"파일입니다.의 경우 30MB XML 파일(는 것이 좋습니다 것이 큰 XML 파일),그것은 아마에게 어떤 차이도 없을 것이다.의 경우 500MB XML 파일을 사용하여 XmlDocument 가 될 것이 매우 문제가 없는 시스템에서의 상당한 금액을 RAM(그 경우에,그러나 내가 주장하는 시간을 수동으로 선택을 통해 파일 형식화된 데이터 읽는 것이 더 중요한 장애물).

지 유형의 처리 하고 있지만,매우 큰 XML,나는 항상 팬의 이벤트 기반으로 처리됩니다.어쩌면 그것은 나 자바 배경,그러나 정말처럼 색소폰.당신이해야 할 당신의 자신의 상태로 관리하지만,일단 당신이 과거는,그것은 매우 효율적인 방법의 분석 XML.

http://saxdotnet.sourceforge.net/

나와 함께 가 youphoric 하나입니다.에 대한 매우 큰 파일을 삭스(또는 어떤 다른 스트리밍 parser)큰 도움이 될 것입니다에서 처리합니다.사용 돔 수집할 수 있습니다 단지 최고 수준의 노드,하지만 당신은 여전히 분석하는 전체 문서를 다운로드하거나 자을 사용하여 스트리밍을 파서 및 이벤트 기반으로 처리할 수 있"skip"노드 당신에 관심이 없;하게 처리 더 빠르다.

지 않은 경우 알레르기 Perl,다음 XML::나뭇가지 제공하는 도구라는 이름 xml_split 할 수 있는 분할 문서를 생산,구성된 XML 섹션입니다.분할할 수 있습 수준에서,나무의 크기에 의하여 또는 XPath 표현이다.

당신처럼 보이는 작업 중 C#다.NET3.5.나는 어디서도 만나볼 수 없는 게시물을 사용하는 것이 좋 수익 유형의 알고리즘에 파일을 스트림으로 의 토대로 몇 가지 요소.

여기에 몇 블로그 게시물 시작하는 길:

나는 유튜브 동영상을 보여주는 분리하는 방법 XML 파일폭스 (무료 XML 편집기 Firstobject 를)사용하여 적은 양의 메모리의 크기에 관계없이 입력 및 출력 파일이 있습니다.

메모리 사용량에 대한 이 CMarkup XML 리더(풀 parser)및 XML 작가 솔루션에 따라 달라의 크기는 하위는 개별적으로 전송 입력 파일에서 출력 파일 또는 최소한 블럭의 크기는 16KB 입니다.

split()
{
  CMarkup xmlInput, xmlOutput;
  xmlInput.Open( "50MB.xml", MDF_READFILE );
  int nObjectCount = 0, nFileCount = 0;
  while ( xmlInput.FindElem("//ACT") )
  {
    if ( nObjectCount == 0 )
    {
      ++nFileCount;
      xmlOutput.Open( "piece" + nFileCount + ".xml", MDF_WRITEFILE );
      xmlOutput.AddElem( "root" );
      xmlOutput.IntoElem();
    }
    xmlOutput.AddSubDoc( xmlInput.GetSubDoc() );
    ++nObjectCount;
    if ( nObjectCount == 5 )
    {
      xmlOutput.Close();
      nObjectCount = 0;
    }
  }
  if ( nObjectCount )
    xmlOutput.Close();
  xmlInput.Close();
  return nFileCount;
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top