繁体   English   中英

在Java中使用StAX的代码

[英]Code for Using StAX in java

我有以下形式的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> School和class的属性也必须保留在结果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标签。 我需要读者有schoolclass ,然后有n个students 因此生成的文件具有与原始文件类似的结构,但每个文件的子文件较少。

提前致谢。

您有用于确定何时启动新文件的代码,我尚未仔细检查过,但是完成一个文件并启动下一个文件的过程肯定是不完整的。

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

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

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM