0

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?
3
  • You can use stax writer. And write what you just read. You should write to different file and then delete original file and rename temp file. Commented Jun 19, 2015 at 15:09
  • Wouldn't writing a new file involve reading every element from the original into memory? Commented Jun 19, 2015 at 15:13
  • Yes. But it is unavoidable. You need to find a place where to edit somehow. Commented Jun 19, 2015 at 15:21

2 Answers 2

1

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.

Sign up to request clarification or add additional context in comments.

1 Comment

I cannot change my implementation from XML to a database, JAXB is a nice idea but involves far too much overhead for me to bother.
0

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

    }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.