Can I force JAXB not to convert " into ", for example, when marshalling to XML?

后端 未结 14 1969
情深已故
情深已故 2020-11-29 09:27

I have an Object that is being marshalled to XML using JAXB. One element contains a String that includes quotes (\"). The resulting XML has " where t

相关标签:
14条回答
  • 2020-11-29 09:52

    Solution my teammate found:

    PrintWriter printWriter = new PrintWriter(new FileWriter(xmlFile));
    DataWriter dataWriter = new DataWriter(printWriter, "UTF-8", DumbEscapeHandler.theInstance);
    marshaller.marshal(request, dataWriter);
    

    Instead of passing the xmlFile to marshal(), pass the DataWriter which knows both the encoding and an appropriate escape handler, if any.

    Note: Since DataWriter and DumbEscapeHandler are both within the com.sun.xml.internal.bind.marshaller package, you must bootstrap javac.

    0 讨论(0)
  • 2020-11-29 09:54

    The simplest way, when using sun's Marshaller implementation is to provide your own implementation of the CharacterEscapeEncoder which does not escape anything.

        Marshaller m = jcb.createMarshaller();
    m.setProperty(
        "com.sun.xml.bind.marshaller.CharacterEscapeHandler",
        new NullCharacterEscapeHandler());
    

    With

    public class NullCharacterEscapeHandler implements CharacterEscapeHandler {
    
        public NullCharacterEscapeHandler() {
            super();
        }
    
    
        public void escape(char[] ch, int start, int length, boolean isAttVal, Writer writer) throws IOException {
            writer.write( ch, start, length );
        }
    }
    
    0 讨论(0)
  • 2020-11-29 09:55

    I have just made my custom handler as a class like this:

    import java.io.IOException;
    import java.io.StringWriter;
    import java.io.Writer;
    
    import com.sun.xml.bind.marshaller.CharacterEscapeHandler;
    
    public class XmlCharacterHandler implements CharacterEscapeHandler {
    
        public void escape(char[] buf, int start, int len, boolean isAttValue,
                Writer out) throws IOException {
            StringWriter buffer = new StringWriter();
    
            for (int i = start; i < start + len; i++) {
                buffer.write(buf[i]);
            }
    
            String st = buffer.toString();
    
            if (!st.contains("CDATA")) {
                st = buffer.toString().replace("&", "&amp;").replace("<", "&lt;")
                    .replace(">", "&gt;").replace("'", "&apos;")
                    .replace("\"", "&quot;");
    
            }
            out.write(st);
            System.out.println(st);
        }
    
    }
    

    in the marshaller method simply call:

    marshaller.setProperty(CharacterEscapeHandler.class.getName(),
                    new XmlCharacterHandler());
    

    it works fine.

    0 讨论(0)
  • 2020-11-29 09:56

    This works for me after reading other posts:

    javax.xml.bind.JAXBContext jc = javax.xml.bind.JAXBContext.newInstance(object);
    marshaller = jc.createMarshaller();         marshaller.setProperty(javax.xml.bind.Marshaller.JAXB_FORMATTED_OUTPUT, true);
    marshaller.setProperty(javax.xml.bind.Marshaller.JAXB_ENCODING, "UTF-8");                   marshaller.setProperty(CharacterEscapeHandler.class.getName(), new CustomCharacterEscapeHandler());
    
    
    public static class CustomCharacterEscapeHandler implements CharacterEscapeHandler {
            /**
             * Escape characters inside the buffer and send the output to the Writer.
             * (prevent <b> to be converted &lt;b&gt; but still ok for a<5.)
             */
            public void escape(char[] buf, int start, int len, boolean isAttValue, Writer out) throws IOException {
                if (buf != null){
                    StringBuilder sb = new StringBuilder();
                    for (int i = start; i < start + len; i++) {
                        char ch = buf[i];
    
                        //by adding these, it prevent the problem happened when unmarshalling
                        if (ch == '&') {
                            sb.append("&amp;");
                            continue;
                        }
    
                        if (ch == '"' && isAttValue) {
                            sb.append("&quot;");
                            continue;
                        }
    
                        if (ch == '\'' && isAttValue) {
                            sb.append("&apos;");
                            continue;
                        }
    
    
                        // otherwise print normally
                        sb.append(ch);
                    }
    
                    //Make corrections of unintended changes
                    String st = sb.toString();
    
                    st = st.replace("&amp;quot;", "&quot;")
                           .replace("&amp;lt;", "&lt;")
                           .replace("&amp;gt;", "&gt;")
                           .replace("&amp;apos;", "&apos;")
                           .replace("&amp;amp;", "&amp;");
    
                    out.write(st);
                }
            }
        }
    
    0 讨论(0)
  • 2020-11-29 09:56

    interesting but with strings you can try out

    Marshaller marshaller = jaxbContext.createMarshaller();
    StringWriter sw = new StringWriter();
    marshaller.marshal(data, sw);
    sw.toString();
    

    at least for me this do not escape quotes

    0 讨论(0)
  • 2020-11-29 09:58

    For some reason I have no time to find out, it worked for me when setting

    marshaller.setProperty(Marshaller.JAXB_ENCODING, "utf-8");
    

    As opposed to using "UTF-8" or "Unicode"

    I suggest you try them, and as @Javatar said, check them dumping to file using:

    marshaller.marshal(shipOrder, new File("<test_file_path>"));
    

    and opening it with a a decent text editor like notepad++

    0 讨论(0)
提交回复
热议问题