【问题标题】:Code for Using StAX in java在 java 中使用 StAX 的代码
【发布时间】:2011-06-24 10:27:31
【问题描述】:

我有一个 200 MB 的 xml,格式如下:

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

我需要将此 xml 拆分为多个文件,使用 StAX 这样每个 xml 文件下有 n 个学生,结构保留为 &lt;school&gt; 然后 &lt;class&gt;&lt;students&gt; 在他们下面。 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。以便生成的文件具有与原始文件类似的结构,只是每个文件的子项较少。

提前致谢。

【问题讨论】:

  • 这不是代码生成服务。自己尝试(使用您找到的示例)并在遇到问题时发布具体问题。
  • 然后发布您的尝试并解释您遇到的问题。我确实想提供帮助,但我不想成为代码生成服务(我不希望这个网站成为其中之一)。
  • 请不要谴责声望大约是您的 260 倍的用户。
  • 我想你可能要考虑使用 vtd-xml 来做,不仅会更快,而且更容易(你可以使用 xpath)

标签: java xml stax


【解决方案1】:

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

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

      【解决方案3】:

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

      使用此链接作为起点XML parsing with JAXB

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

      【讨论】:

      • 问题是 XML 是 200MB,如果使用 JAXB 将整个 XML 解析成对象树,可能会耗尽内存。
      • @Alvin 200mb 是一个安静的大文件——但我认为通过拆分根文件的设计方法并不能解决他的内存管理问题,甚至是灵活性问题。如果学生文件增长到 200Mb 怎么办?!然后另一个例程将其分解?!
      • 我的问题正是你所怀疑的。如果任何文件增长超过一定大小,它将再次被分解。
      • 但现在我唯一关心的是破坏文件,只分发孩子并保留层次结构。
      • @Anand 在这种情况下,我会指出你回到唐罗比的答案。
      猜你喜欢
      • 2012-03-20
      • 1970-01-01
      • 2013-05-24
      • 1970-01-01
      • 1970-01-01
      • 2023-03-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多