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

时间:2010-12-14 04:39:38

标签: java jaxb escaping character marshalling

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

"<"tagA>
**"<"YYYYY>done"<"/YYYYY>**
"<"/tagA>

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

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

"&"lt;YYYYY"&"gt;"&"#xD;done ...&amp;等等

我无法使用JAXB 2.2单独处理这些转义字符 反正有可能吗?

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

提前致谢, 阿比纳夫·米什拉

5 个答案:

答案 0 :(得分:8)

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

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

答案 1 :(得分:7)

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

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 );

转义字符问题将得到解决

答案 2 :(得分:2)

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

它描述了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;
   }

}

有关详细信息,请参阅:

答案 3 :(得分:1)

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

  • 禁用字符转义
  • 或使用CDATA字符串,只需稍加配置就可以将支持添加到JAXB中

答案 4 :(得分:1)

如果您希望完全控制要转义哪些字符(例如“\'”),则使用JAXB编组程序,您将不得不添加属性:

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("&amp;");
                        break;
                    case '<':
                        out.write("&lt;");
                        break;
                    case '>':
                        out.write("&gt;");
                        break;
                    case '\"':
                        out.write("&quot;");
                        break;
                    case '\'':
                        out.write("&apos;");
                        break;
                }
            }
        }

        if( start!=limit )
            out.write(ch,start,limit-start);
    }
}

希望有所帮助。