Stax2 XMLReader/Writer: Prevent decoding of Attribute values

21 Views Asked by At

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

There are 0 best solutions below