使用JAXB Marshaller处理XML转义字符(例如引号)

我需要使用JAXB Marshaller(JAXB 2.2版)将XML java对象序列化为XML文件。 现在在xml对象中,我有一个包含String值的标记,这样:

" **"done"** " 

现在您可以看到此字符串值再次包含标记。 我希望在xml文件中以相同的方式编写它。

但JAXB Marshaller会转换这些值,例如:

"&"lt;YYYYY"&"gt;"&"#xD;done ……等等

我无法使用JAXB 2.2单独处理这些转义字符。无论如何它是否可能?

在这方面的任何帮助都会很棒..

在此先感谢Abhinav Mishra

通过为JAXB Marshaller设置以下属性来完成它:

 marshaller.setProperty("jaxb.encoding", "Unicode"); 

有一种更简单的方法。 首先使用自定义转义序列:

 m.setProperty(CharacterEscapeHandler.class.getName(), new CharacterEscapeHandler() { @Override public void escape(char[] ch, int start, int length, boolean isAttVal, Writer out) throws IOException { out.write( ch, start, length ); } }); 

然后将其编组为如下所述的字符串

 StringWriter writer = new StringWriter(); m.marshal(marshalObject, writer); 

然后从下面提到的编写器创建一个文档对象

 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); InputSource is = new InputSource( new StringReader( writer.toString() ) ); Document doc = builder.parse( is ); 

转义字符问题将得到解决

您可以利用CDATA结构。 标准JAXB不包括此结构。 EclipseLink JAXB(MOXy)中有一个扩展(我是技术主管)。 看看我对相关问题的回答:

  • 如何使用JAXB生成CDATA块?

它描述了MOXy中的@XmlCDATA注释:

 import javax.xml.bind.annotation.XmlRootElement; import org.eclipse.persistence.oxm.annotations.XmlCDATA; @XmlRootElement(name="c") public class Customer { private String bio; @XmlCDATA public void setBio(String bio) { this.bio = bio; } public String getBio() { return bio; } } 

有关更多信息,请参阅

根据您正在寻找的内容,您可以:

  • 禁用字符转义
  • 或者使用CDATA字符串,可以通过一些配置将支持添加到JAXB中

使用JAXB marshaller如果要完全控制要转义的字符(例如“\”“),则必须添加属性:

 Marshaller marshaller = jc.createMarshaller(); marshaller.setProperty(CharacterEscapeHandler.class.getName(), new CustomCharacterEscapeHandler()); 

并创建一个新的CustomCharacterEscapeHandler类

 import com.sun.xml.bind.marshaller.CharacterEscapeHandler; import java.io.IOException; import java.io.Writer; public class CustomCharacterEscapeHandler implements CharacterEscapeHandler { public CustomCharacterEscapeHandler() { super(); } public void escape(char[] ch, int start, int length, boolean isAttVal, Writer out) throws IOException { // avoid calling the Writerwrite method too much by assuming // that the escaping occurs rarely. // profiling revealed that this is faster than the naive code. int limit = start+length; for (int i = start; i < limit; i++) { char c = ch[i]; if(c == '&' || c == '<' || c == '>' || c == '\'' || (c == '\"' && isAttVal) ) { if(i!=start) out.write(ch,start,i-start); start = i+1; switch (ch[i]) { case '&': out.write("&"); break; case '<': out.write("<"); break; case '>': out.write(">"); break; case '\"': out.write("""); break; case '\'': out.write("'"); break; } } } if( start!=limit ) out.write(ch,start,limit-start); } } 

希望有所帮助。