How to write unescaped XML to XMLStreamWriter?
Asked Answered
F

3

5

I have a number of small XML chunks, that should be embedded in one big XML as child elements. Is there any way to write these chunks to XMLStreamWriter without escaping them?

Fourchette answered 15/11, 2013 at 10:6 Comment(6)
I don't think you can. It would be far too easy to write broken XML that way.Annoying
You could transform your XML with an Xslt identity transform and output the result to a StaxResult based on your XMLStreamWriter...Annoying
@JoachimSauer Sure it would. But let's assume I know what I'm trying to do :).Fourchette
I didn't try to imply otherwise ;-) I was just trying to explain a likely reason why this interface is lacking that (kind-of obvious) feature. I think going the path via an identity transformer (just as if writing to a file) is the way to go hereAnnoying
Thanks for idea. Maybe it makes sense to put it to answer?Fourchette
For an answer I'd have to look up the details, I don't think what I wrote here is answer-worthy. But feel free to put it as an answer yourself when you've figured out the nitty-gritty ;-)Annoying
P
8

Below are a couple of options for handling this:

Option #1 - Use javax.xml.transform.Transformer

You could use a javax.xml.transform.Transformer to transform a StreamSource representing your XML fragment onto your StAXResult which is wrapping your XMLStreamWriter.

Option #2 - Interact Directly with the OutputStream

Alternatively you could do something like the following. You can leverage flush() to force the XMLStreamWriter to output its contents. Then you'll note that I do xsw.writeCharacters("") this forces the start element to end for bar before writing the nested XML as a String. The sample code below needs to be flushed out to properly handle encoding issues.

import java.io.*;
import javax.xml.stream.*;

public class Demo {

    public static void main(String[] args) throws Exception {
        OutputStream stream = System.out;
        
        XMLOutputFactory xof = XMLOutputFactory.newFactory();
        XMLStreamWriter xsw = xof.createXMLStreamWriter(stream);
        
        xsw.writeStartDocument();
        xsw.writeStartElement("foo");
        xsw.writeStartElement("bar");
        
        /* Following line is very important, without it unescaped data 
           will appear inside the <bar> tag. */
        xsw.writeCharacters("");
        xsw.flush();
        
        OutputStreamWriter osw = new OutputStreamWriter(stream);
        osw.write("<baz>Hello World<baz>");
        osw.flush();
        
        xsw.writeEndElement();
        xsw.writeEndElement();
        xsw.writeEndDocument();
        xsw.close();
    }

}
Portemonnaie answered 15/11, 2013 at 11:54 Comment(3)
With the second approach you'd have to be careful to use the exact same encoding in the OutputStreamWriter than the output factory is configured to. Even defaulting to UTF-8 would be more likely to work than just using the platform default encoding (as you currently do).Annoying
I didn't get option #1 to work. The transform inserts a <?xml version="1.0"?> at the beginning of the fragment and closes of the original tags at the end(in your example the foo and bar elements would be closed after the transformer has run. Try it to see what I mean.Anthropophagy
Could you possibly provide an example of option 1?Dumortierite
B
2

woodstox has a stax implementation and their XMLStreamWriter2 class has a writeRaw() call. We have the same need and this gave us a very nice solution.

Basidiospore answered 27/3, 2014 at 15:22 Comment(0)
A
2
final XMLOutputFactory streamWriterFactory = XMLOutputFactory.newFactory();
streamWriterFactory.setProperty("escapeCharacters", false);

From here

Antilogarithm answered 2/12, 2015 at 21:8 Comment(2)
It simplest solution! Thank you.Gaytan
Xerces specific.Cissiee

© 2022 - 2024 — McMap. All rights reserved.