0

I have an 200 MB xml of the following form:

      <school name = "some school">
        <class standard = "2A">
           <student>  
             ..... 
           </student>
           <student>  
             ..... 
           </student>
           <student>  
             ..... 
           </student>
         </class>
       </school>

I need to split this xml into several files using StAX such that n students come under each xml file and the structure is preserved as <school> then <class> and <students> under them. The attributes of School and class also must be preserved in the resultant xmls.

Here is the code I am using:

XMLInputFactory inputFactory = XMLInputFactory.newInstance();

    String xmlFile = "input.XML";
    XMLEventReader reader = inputFactory.createXMLEventReader(new FileReader(xmlFile));

    XMLOutputFactory outputFactory = XMLOutputFactory.newInstance();
    outputFactory.setProperty("javax.xml.stream.isRepairingNamespaces", Boolean.TRUE);

    XMLEventWriter writer = null;

    int count = 0;

    QName name = new QName(null, "student");

    try {
        while (true) {
            XMLEvent event = reader.nextEvent();
            if (event.isStartElement()) {
                StartElement element = event.asStartElement();
                if (element.getName().equals(name)) {
                    String filename = "input"+ count + ".xml";
                    writer = outputFactory.createXMLEventWriter(new FileWriter(filename));
                    writeToFile(reader, event, writer);
                    writer.close();
                    count++;
                }
            }
            if (event.isEndDocument())
                break;
        }
    } catch (XMLStreamException e) {
        throw e;
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        reader.close();
    }

private static void writeToFile(XMLEventReader reader, XMLEvent startEvent, XMLEventWriter writer) throws XMLStreamException, IOException {

    StartElement element = startEvent.asStartElement();
    QName name = element.getName();
    int stack = 1;

    writer.add(element);

    while (true) {
        XMLEvent event = reader.nextEvent();
        if (event.isStartElement() && event.asStartElement().getName().equals(name))
            stack++;
        if (event.isEndElement()) {
            EndElement end = event.asEndElement();
            if (end.getName().equals(name)) {
                stack--;
                if (stack == 0) {
                    writer.add(event);
                    break;
                }
            }
        }
        writer.add(event);
    }

}

Please check the function call writeToFile(reader, event, writer) in the try block. Here the reader object has only the student tag. I need the reader has the school, class, and then n students in it. so that the file generated has a similar structure as the original only with lesser children per file.

Thanks in advance.

4

3 に答える 3

0

新しいファイルをいつ開始するかを決定するためのコードがありますが、これは詳しく調べていませんが、1 つのファイルを終了して次のファイルを開始するプロセスは明らかに不完全です。

ファイルを終了したいポイントに到達したら、ドキュメントを閉じる前に、囲ん<class><school>いるタグとドキュメントの終了イベントを生成する必要があります。新しいファイルを開始するときは、ファイルを開いた後、生徒のイベントのコピーを再開する前に、同じファイルの開始イベントを生成する必要があります。

開始イベントを適切に生成するには、入力から対応するイベントを保持する必要があります。

于 2011-06-24T11:05:52.157 に答える
0

手間と時間を節約し、現在持っているフラットな xml ファイル構造を使用してから、あなたが述べたように各オブジェクトを表す POJO オブジェクトを作成します。学生学校クラス。そして、Jaxb を使用して、オブジェクトを構造の異なる部分にバインドします。その後、xml を効果的にアンマーシャリングし、SQL オブジェクトを扱っているかのようにさまざまな要素にアクセスできます。

このリンクを JAXB による XML 解析の出発点として使用してください。

この方法で行う 1 つの問題は、メモリの消費です。設計の柔軟性とメモリ管理のために、SQL を使用してこれを処理することをお勧めします。

于 2011-06-24T11:09:25.227 に答える
0

「学生」開始要素イベントの前に親イベントのリストを追跡し、それを writeToFile() メソッドに渡すことができると思います。次に writeToFile() メソッドで、そのリストを使用して「学校」と「クラス」のイベントをシミュレートできます。

于 2011-06-24T11:14:26.707 に答える