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?
Asked
Active
Viewed 5,078 times
5

Andrei Petrenko
- 3,922
- 3
- 31
- 53
-
I don't think you can. It would be *far* too easy to write broken XML that way. – Joachim Sauer Nov 15 '13 at 10:24
-
You could transform your XML with an Xslt identity transform and output the result to a StaxResult based on your XMLStreamWriter... – Joachim Sauer Nov 15 '13 at 10:26
-
@JoachimSauer Sure it would. But let's assume I know what I'm trying to do :). – Andrei Petrenko Nov 15 '13 at 10:27
-
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 here – Joachim Sauer Nov 15 '13 at 10:41
-
Thanks for idea. Maybe it makes sense to put it to answer? – Andrei Petrenko Nov 15 '13 at 10:47
-
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 ;-) – Joachim Sauer Nov 15 '13 at 10:53
3 Answers
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();
}
}

Kristof Jozsa
- 6,612
- 4
- 28
- 32

bdoughan
- 147,609
- 23
- 300
- 400
-
1With 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). – Joachim Sauer Nov 17 '13 at 11:14
-
I didn't get option #1 to work. The transform inserts a `` 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. – Roland Jul 18 '16 at 09:09
-
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.

David Thielen
- 28,723
- 34
- 119
- 193
2
final XMLOutputFactory streamWriterFactory = XMLOutputFactory.newFactory();
streamWriterFactory.setProperty("escapeCharacters", false);