Search code examples
javaxmlxml-parsingeclipselinkmoxy

prevent eclipselink moxy from escaping element contents


I have the following class:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "item", propOrder = {
    "content"
})
public class Item {

    @XmlElementRefs({
        @XmlElementRef(name = "ruleref", type = JAXBElement.class, required = false),
        @XmlElementRef(name = "tag", type = JAXBElement.class, required = false),
        @XmlElementRef(name = "one-of", type = JAXBElement.class, required = false),
        @XmlElementRef(name = "item", type = JAXBElement.class, required = false)
    })    
    @XmlMixed
    protected List<Serializable> content;

The elements can contain strings that have quotes in them, such as:

<tag>"some kind of text"</tag>

Additionally, the item element itself can have strings with quotes in them:

<item>Some text, "this has string"</item>

The generated XML when using Moxy escapes the text value in the tag and item elements:

<tag>&quote;some kind of text&quote;</tag>

How can i prevent it from doing that, but only in these elements? Attributes and other elements should be left unchanged (escaped i mean).

Thank you.


Solution

  • You can override the default character escaping by supplying your own CharacterEscapeHandler.

    Java Model

    Foo

    import javax.xml.bind.annotation.XmlRootElement;
    
    @XmlRootElement
    public class Foo {
    
        private String bar;
    
        public String getBar() {
            return bar;
        }
    
        public void setBar(String bar) {
            this.bar = bar;
        }
    
    }
    

    Demo Code

    Demo

    import java.io.*;
    import javax.xml.bind.*;
    import org.eclipse.persistence.jaxb.MarshallerProperties;
    import org.eclipse.persistence.oxm.CharacterEscapeHandler;
    
    public class Demo {
    
        public static void main(String[] args) throws Exception {
            JAXBContext jc = JAXBContext.newInstance(Foo.class);
    
            Foo foo = new Foo();
            foo.setBar("\"Hello World\"");
    
            Marshaller marshaller = jc.createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            marshaller.marshal(foo, System.out);
    
            marshaller.setProperty(MarshallerProperties.CHARACTER_ESCAPE_HANDLER, new CharacterEscapeHandler() {
    
                @Override
                public void escape(char[] buffer, int start, int length,
                        boolean isAttributeValue, Writer out) throws IOException {
                    out.write(buffer, start, length);
                }
    
            });
    
            marshaller.marshal(foo, System.out);
        }
    
    }
    

    Output

    <?xml version="1.0" encoding="UTF-8"?>
    <foo>
       <bar>&quot;Hello World&quot;</bar>
    </foo>
    <?xml version="1.0" encoding="UTF-8"?>
    <foo>
       <bar>"Hello World"</bar>
    </foo>