2016-08-11 186 views
1

我試圖使用JAXB序列化一個類,該JAXB具有一些CDATA字段,並且某些字段包含需要轉義的特殊字符(包括<和>)。問題是我無法讓這兩種情況下的轉義處理正常工作。在不轉義CDATA標籤的情況下轉義XML字符

使用自定義CDATA適配器,如果我設置我的編組的下列財產,

jaxbMarshaller.setProperty(CharacterEscapeHandler.class.getName(), 
     (CharacterEscapeHandler) (ch, start, length, isAttVal, out) -> out.write(ch, start, length)); 

我得到:

<key1><![CDATA[Test]]></key1> # What I want 
<key2>some_>_value</key2>  # Invalid XML 

如果刪除該屬性並讓JAXB處理其自己的逃逸,我得到:

<key1>&lt;![CDATA[Test]]&gt; # Not what I want 
<key2>some_&lt;_value</key2> # What I want 

但我需要的是:

<key1><![CDATA[Test]]></key1> 
<key2>some_&lt;_value</key2> 

有沒有什麼辦法可以讓我的轉義處理函數這樣呢?

回答

0

您可以使用com.sun.xml.bind.marshaller.CharacterEscapeHandler界面來解決您的問題。

示例Java類:

import javax.xml.bind.annotation.XmlElement; 
import javax.xml.bind.annotation.XmlRootElement; 

@XmlRootElement 
public class AA { 

    String B; 
    String C; 


    public String getB() { 
     return B; 
    } 

    @XmlElement 
    public void setB(String b) { 
     B = b; 
    } 

    @Override 
    public String toString() { 
     return "AA [B=" + B + ", C=" + C + ", D=" + D + "]"; 
    } 

    public String getC() { 
     return C; 
    } 

    @XmlElement 
    public void setC(String c) { 
     C = c; 
    } 

    public String getD() { 
     return D; 
    } 

    @XmlElement 
    public void setD(String d) { 
     D = d; 
    } 

    String D; 
} 

示例XML:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<aa> 
    <b>Title of Feed Item</b> 
    <c>some_>_value</c> 
    <d> 
    <![CDATA[Test]]> 
    </d> 
</aa> 

系列化電話:

AA ref = new AA(); 
ref.setB("Title of Feed Item"); 
ref.setC("some_>_value"); 
ref.setD("<![CDATA[Test]]>"); 
File file = new File("Test.xml"); 
JAXBContext jaxbContext = JAXBContext.newInstance(AA.class); 
Marshaller jaxbMarshaller = jaxbContext.createMarshaller(); 
jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 
final Map<String, String> replacement=new HashMap<String, String>(); 
    replacement.put(">", "&gt;"); 
    replacement.put("<", "&lt;"); 
    final Pattern pattern=Pattern.compile("[<|>]"); 

jaxbMarshaller.setProperty(CharacterEscapeHandler.class.getName(), 
      new CharacterEscapeHandler() { 

       @Override 
       public void escape(char[] arg0, int arg1, int arg2, 
         boolean arg3, Writer arg4) throws IOException { 
        if (String.valueOf(arg0).contains("CDATA")) 
         arg4.write(arg0, arg1, arg2); 
        else { 
         StringBuffer buffer = new StringBuffer(); 
         Matcher matcher = pattern.matcher(String 
           .valueOf(arg0)); 
         while (matcher.find()) { 
          matcher.appendReplacement(buffer, 
            replacement.get(matcher.group())); 
         } 
         matcher.appendTail(buffer); 
         char t[] = buffer.toString().toCharArray(); 
         arg4.write(t, arg1, t.length); 
        } 
       } 
      }); 



jaxbMarshaller.marshal(ref, file); 
jaxbMarshaller.marshal(ref, System.out); 

編輯:我已經修改了代碼,使用正則表達式的括號。

對於正則表達式的樣品我已經提到this link

+0

據我所看到的,這仍然會給我錯誤的結果,因爲'一些_> _值'是無效的XML。 –