我有以下形式的200 MB xml:
<school name = "some school">
<class standard = "2A">
<student>
.....
</student>
<student>
.....
</student>
<student>
.....
</student>
</class>
</school>
我需要使用StAX 将此xml拆分为多个文件,例如学生们在每个xml文件下,结构将保留为<school>
,然后{ {1}}和<class>
在他们之下。学校和班级的属性也必须保留在生成的xmls中。
以下是我正在使用的代码:
<students>
请检查try块中的函数调用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);
}
}
。这里reader对象只有writeToFile(reader, event, writer)
标签。我需要读者拥有student
,school
,然后是class
。这样生成的文件就具有与原始文件类似的结构,只有每个文件的子项较少。
提前致谢。
答案 0 :(得分:0)
你有代码来确定何时开始我没有仔细检查的新文件,但是完成一个文件并开始下一个文件的过程肯定是不完整的。
在到达要结束文件的位置时,您必须为封闭的<class>
和<school>
标记以及关闭之前的文档生成结束事件。当您启动新文件时,您需要在打开它之后以及再次开始复制学生事件之前为其生成启动事件。
为了正确生成启动事件,您必须保留输入中的相应事件。
答案 1 :(得分:0)
节省您自己的麻烦和时间,并使用您当前拥有的平面xml文件结构,然后创建POJO对象,它将代表您所述的每个对象; 学生,学校和班级。然后使用Jaxb将对象绑定到Structure的不同部分。然后,您可以有效地解组xml并访问各种元素,就像处理SQL对象一样。
使用此链接作为起点XML parsing with JAXB
这样做的一个问题是内存消耗。为了设计灵活性和内存管理,我建议使用SQL来处理这个问题。
答案 2 :(得分:0)
我认为您可以在“student”start元素事件之前跟踪父事件列表,并将其传递给writeToFile()方法。然后在writeToFile()方法中,您可以使用该列表来模拟“school”和“class”事件。