Search code examples
javaxmlwoodstox

Java: Set attributes on XMLStreamReader2?


I'm using Woodstox to stream XML documents in my application. I need to set default attributes on elements as defined by the schema before they are processed, but the only way to do this with Woodstox is to read the document into memory with an extra XMLStreamReader with some logic to write the default attributes, write it out to an in-memory XML document, and then pass the in-memory document into the business-logic.

I don't like this. I want to stream the document per element to keep the memory footprint low because the documents can be potentially big and I'm running multiple instances of this in the application. Is there a way to inject attributes into the XMLStreamReader while streaming the document? I already found a way to skip over nodes I'm not interested in while streaming:

public class XMLPreProcessor extends StreamReader2Delegate {
    public XMLPreProcessor(XMLStreamReader2 sr) {
        super(sr);
    }

    //Skip over all processing instructions
    //Can this be extended to inject attributes to elements?
    @Override
    public int next() throws XMLStreamException {
        int eventType = super.next();

        while(eventType == XMLStreamConstants.PROCESSING_INSTRUCTION) {
            eventType = super.next();
        }

        return eventType;
    }
}

Can this delegate be tweaked to inject attributes into the XMLStreamReader?


Solution

  • No I don't think there is such facility to inject content. If you were using Event API (XMLEventReader), you could probably modify element objects, however.

    However: your approach, using delegate, might work. You would need to override all methods that access attributes, and keep state of additional attributes. So when asked how many attributes there are, you'd return original count plus injected attributes; and probably virtually append new ones after original. This sounds doable; you may also need to override next() to update state whenever START_ELEMENT is read, discard after advancing.