Java Modify XML

375 views Asked by At

I want to read an XML file in Java and then update certain elements in that file with new values. My file is > 200mb and performance is important, so the DOM model cannot be used.

I feel that a StaX Parser is the solution, but there is no decent literature on using Java StaX to read and then write XML back to the same file.

(For reference I have been using the java tutorial and this helpful tutorial to get what I have so far)

I am using Java 7, but there doesn't seem to be any updates to the XML parsing API since...a long time ago. So this probably isn't relevant.

Currently I have this:

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

which will read the XMLFile and return the value of the selected element. However, I have another method updateXMLFile(final File xmlFile, final String value) which I want to use in conjunction with this.

So my question is threefold:

  1. Is there a StaX implementation for editing XML
  2. Will XPath be any help? Can that be used without converting my file to a Document?
  3. (More Generally) Why doesn't Java have a better XML API?
2

There are 2 answers

0
Rossiar On BEST ANSWER

This is my approach, which reads events from the file using StaX and writes them to another file. The values are updated as the loop passes over the correctly named elements.

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

    }
1
John Kuhns On

There are two things you may want to look at. The first is to use JAXB to bind the XML to POJOs which you can then have your way with and serialize the structure back to XML when needed.

The second is a JDBC driver for XML, there are several available for a fee, not sure if there are any open source ones or not. In my experience JAXB is the better choice. If the XML file is too large to handle efficiently with JAXB I think you need to look at using a database as a replacement for the XML file.