Java修改XML

Java Modify XML

我想读取Java中的XML文件,然后更新该文件中的某些元素具有新的价值。我的文件大于 200mb,性能很重要,所以不能使用 DOM 模型。

我觉得 StaX 解析器是解决方案,但没有关于使用 Java StaX 进行 读取和写入的体面文献 XML 回到同一个文件。

(作为参考,我一直在使用 the java tutorial and this helpful tutorial 来获得我目前所拥有的)

我正在使用 Java 7,但自从...很久以前以来,XML 解析 API 似乎没有任何更新。所以这可能不相关。

目前我有这个:

public static String readValueFromXML(final File xmlFile, final String value) throws FileNotFoundException, XMLStreamException
{
    XMLEventReader reader = new XMLInputFactory.newFactory().createXMLEventReader(new FileReader(xmlFile));

    String found = "";
    boolean read = false;

    while (reader.hasNext())
    {
        XMLEvent event = reader.nextEvent();
        if (event.isStartElement() &&
            event.asStartElement().getName().getLocalPart().equals(value))
        {
            read = true;
        }

        if (event.isCharacters() && read)
        {
            found = event.asCharacters().getData();
            break;
        }
    }

    return found;
}

这将读取 XML 文件和 return 所选元素的值。但是,我有另一种方法 updateXMLFile(final File xmlFile, final String value),我想将其与此结合使用。

所以我的问题有三个:

  1. 是否有用于编辑的 StaX 实现 XML
  2. XPath 会有帮助吗?可以在不将我的文件转换为 Document 的情况下使用吗?
  3. (更一般)为什么 Java 没有更好的 XML API?

您可能需要查看两件事。第一种是使用 JAXB 将 XML 绑定到 POJO,然后您可以使用它并在需要时将结构序列化回 XML。

第二个是XML的JDBC驱动,有几个是收费的,不知道有没有开源的。根据我的经验,JAXB 是更好的选择。如果 XML 文件太大而无法使用 JAXB 有效处理,我认为您需要考虑使用数据库来替代 XML 文件。

这是我的方法,它使用 StaX 从文件中读取事件并将它们写入另一个文件。当循环经过正确命名的元素时,值会更新。

public void read(String key, String value) 
    {
        try (FileReader fReader = new FileReader(inputFile); FileWriter fWriter = new FileWriter(outputFile))
        {
            XMLEventFactory factory = XMLEventFactory.newInstance();
            XMLEventReader reader = XMLInputFactory.newFactory().createXMLEventReader(fReader);
            XMLEventWriter writer = XMLOutputFactory.newFactory().createXMLEventWriter(fWriter);

            while (reader.hasNext())
            {
                XMLEvent event = reader.nextEvent();
                boolean update = false;

                if (event.isStartElement() && event.asStartElement().getName().getLocalPart().equals(key))
                {
                        update = true;
                }
                else if (event.isCharacters() && update)
                {
                        Characters characters = factory.createCharacters(value);
                        event = characters;
                        update = false;
                }
                writer.add(event);
            }
        }
        catch (XMLStreamException | FactoryConfigurationError | IOException e)
        {
            e.printStackTrace();
        }

    }