0

我有以下形式的 200 MB xml:

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

我需要使用 StAX将此 xml 拆分为多个文件,以便 n 个学生位于每个 xml 文件下<school><class>并且结构保留<students>在它们之下。学校和班级的属性也必须保留在生成的 xml 中。

这是我正在使用的代码:

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);
    }

}

请检查 try 块中的函数调用writeToFile(reader, event, writer)。这里阅读器对象只有student标签。我需要读者有school, class, 然后是 n students。因此生成的文件具有与原始文件类似的结构,只是每个文件的子项较少。

提前致谢。

4

3 回答 3

0

我认为您可以在“学生”开始元素事件之前跟踪父事件列表并将其传递给 writeToFile() 方法。然后在 writeToFile() 方法中,您可以使用该列表来模拟“学校”和“班级”事件。

于 2011-06-24T11:14:26.707 回答
0

您有确定何时开始新文件的代码,我没有仔细检查过,但是完成一个文件并开始下一个文件的过程肯定是不完整的。

在到达要结束文件的位置时,您必须在关闭文件之前为封闭<class>和标签以及文档生成结束事件。<school>当您开始新文件时,您需要在打开它之后和再次开始复制学生事件之前为其生成开始事件。

为了正确生成开始事件,您必须保留输入中的相应事件。

于 2011-06-24T11:05:52.157 回答
0

节省您的麻烦和时间,并使用您当前拥有的平面 xml 文件结构,然后创建 POJO 对象,该对象将代表您所说的每个对象;学生学校班级。然后使用 Jaxb 将对象与结构的不同部分绑定。然后,您可以有效地解组 xml 并访问各种元素,就像您正在处理 SQL 对象一样。

使用此链接作为使用 JAXB 进行 XML 解析的起点

这样做的一个问题是内存消耗。为了设计灵活性和内存管理,我建议使用 SQL 来处理这个问题。

于 2011-06-24T11:09:25.227 回答