I have to add an element to a received XML. The rest of the XML should remain the same as it was when receiving it (as I'm an intermediary and as a part of the XML could be signed - not the part that I'm modifying).
For simplicity I've decided to use the XMLStreamWriter2 "copyEventFromReader" method. Now I'm facing the issue, that the stax2 XMLReader decodes attribute values. So like ">" will be changed to ">". This would break signatures and should therefore be prevented.
Is there a way to achieve this? I've only found that I could use my own EscapingWriterFactory for the XMLOutputFactory2. But when reaching that method, the decoding already happened (therefore my assumption that the XMLReader does the decoding).
Example xml:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<dummy>
<hello>Welcome</hello>
<test attr="is > 12">23</test>
</dummy>
Code example:
final var xmlOutputFactory2 = new WstxOutputFactory();
final var xmlInputFactory2 = new WstxInputFactory();
XMLStreamReader2 xmlStreamReader = null;
XMLStreamWriter2 xmlStreamWriter = null;
Path target = null;
FileWriter fileWriter = null;
try {
target = File.createTempFile("target", UUID.randomUUID().toString()).toPath();
fileWriter = new FileWriter(target.toFile(), StandardCharsets.UTF_8);
xmlStreamReader = xmlInputFactory2.createXMLStreamReader(new File(ClassLoaderUtils.getResource("file/test.xml", Stax.class).toURI()));
xmlStreamWriter = xmlOutputFactory2.createXMLStreamWriter(fileWriter, StandardCharsets.UTF_8.name());
if (xmlStreamReader.hasNext()) {
// The XML declaration <?xml version="1.0" encoding="UTF-8" ?> is not copied from the source document (╯°□°)╯︵ ┻━┻
xmlStreamWriter.writeStartDocument(StandardCharsets.UTF_8.name(), XML_VERSION);
}
while (xmlStreamReader.hasNext()) {
xmlStreamReader.next();
xmlStreamWriter.copyEventFromReader(xmlStreamReader, true);
}
System.out.println(Files.readString(target));
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (xmlStreamReader != null) xmlStreamReader.closeCompletely();
if (xmlStreamWriter != null) xmlStreamWriter.closeCompletely();
if (target != null) Files.delete(target);
if (fileWriter != null) fileWriter.close();
} catch (Exception e) {
e.printStackTrace();
}
}