使用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); } }
希望有所帮助。