2017-09-13 262 views
0

我需要使用XmlAdapter因爲我想沒有空XLM對象:轉義字符(例如引號)使用JAXB的Marshaller

<TACHES> 
    <TACHE> 
     <NB_HEURE>7.75</NB_HEURE> 
     <NOTES>foo</NOTES> 
     <CODE_TACHE>1234</CODE_TACHE> 
    </TACHE> 
    <TACHE>     <- I Want delete this part 
     <NB_HEURE/>   <- I Want delete this part 
     <NOTES/>   <- I Want delete this part 
     <CODE_TACHE/>  <- I Want delete this part 
    </TACHE>    <- I Want delete this part 
</TACHES> 

我的POJO是:

@XmlRootElement(name = "TACHES") 
public class Tasks { 
    private List<Task> tasks; 
    @XmlJavaTypeAdapter(TaskAdapter.class) 
    @XmlElement(name = "TACHE") 
    public List<Task> getTasks() { 
     return tasks; 
    } 
    public void setTasks(List<Task> tasks) { 
     this.tasks = tasks; 
    } 
} 

我XmlAdapter是:

public class TaskAdapter extends XmlAdapter<String, Task> { 
    @Override 
    public Task unmarshal(String v) throws Exception { 
     return null; 
    } 
    @Override 
    public String marshal(Task t) throws Exception { 
     JAXBContext context = JAXBContext.newInstance(Task.class); 
     Marshaller m = context.createMarshaller(); 
     m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); 
     m.setProperty(Marshaller.JAXB_FRAGMENT, true); 
     m.setProperty("jaxb.encoding", "Unicode"); 
     StringWriter sw = new StringWriter(); 
     if ("".equals(t.getNotes()) && "".equals(t.getHourCount()) && "".equals(t.getTaskCode())) { 
      return null; 
     } 
     m.marshal(t, sw); 
     String s = sw.toString(); 
     s = s.substring(s.indexOf("<TACHE>") + 7, s.indexOf("</TACHE>")); 
     System.out.println(s); 
     return s; 
    } 
} 

XmlAdapter打印的System.out.println:

<NB_HEURE>7.75</NB_HEURE> 
<NOTES>foo</NOTES> 
<CODE_TACHE>1234</CODE_TACHE> 

,但是,當我元帥全球POJO,我有:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
... 
<TACHES> 
    <TACHE> 
     &lt;NB_HEURE&gt;7.75&lt;/NB_HEURE&gt; 
     &lt;NOTES&gt;foo&lt;/NOTES&gt; 
     &lt;CODE_TACHE&gt;1234&lt;/CODE_TACHE&gt; 
    </TACHE> 
</TACHES> 
... 

我的是:

JAXBContext context = JAXBContext.newInstance(MoReports.class); 
Marshaller m = context.createMarshaller(); 
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); 
StringWriter sw = new StringWriter(); 
m.marshal(moReports, sw); 
xmlString = sw.toString(); 
+0

我認爲這是怎麼一回事,因爲JAXB對待標籤(內TACHE)的值,使他們獲得逃過一劫。雖然不是一個優雅的解決方案,但您始終可以使用< and >分別修改生成的XML來替換轉義字符。 –

回答

0

步驟1

我不會用 'TaskAdapter延伸XmlAdapter'

步驟2

我在FALSE

m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.FALSE); 

步驟3

JAXB_FORMATTED_OUTPUT設定和予添加此代碼交編組

xmlString = removeAllEmptyXmlTags(xmlString); 

public String removeAllEmptyXmlTags(String xml) { 
    final String regex1 = "<([a-zA-Z0-9-\\_]*)[^>]*/>"; 
    final String regex2 = "<([a-zA-Z0-9-\\_]*)[^>]*>\\s*</\\1>"; 
    final Pattern pattern1 = Pattern.compile(regex1); 
    final Pattern pattern2 = Pattern.compile(regex2); 

    String xmlString = xml; 

    Matcher matcher1; 
    Matcher matcher2; 
    do { 
     xmlString = xmlString.replaceAll(regex1, "").replaceAll(regex2, ""); 
     matcher1 = pattern1.matcher(xmlString); 
     matcher2 = pattern2.matcher(xmlString); 
    } while (matcher1.find() || matcher2.find()); 

    return xmlString; 
} 

步驟4

,我添加此代碼後元帥

xmlString = xmlIndent(xmlString, false); 

public String xmlIndent(String xml, Boolean ommitXmlDeclaration) { 
    Writer outxml = new StringWriter(); 
    try { 
     DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder(); 
     Document doc = db.parse(new InputSource(new StringReader(xml))); 
     OutputFormat format = new OutputFormat(doc); 
     format.setIndenting(true); 
     format.setIndent(2); 
     format.setOmitXMLDeclaration(ommitXmlDeclaration); 
     format.setLineWidth(Integer.MAX_VALUE); 
     XMLSerializer serializer = new XMLSerializer(outxml, format); 
     serializer.serialize(doc); 
    } catch (ParserConfigurationException | SAXException | IOException e) { 
     return xml; 
    } 
    return outxml.toString(); 
} 

結果是OK:

<TACHES> 
    <TACHE> 
     <NB_HEURE>7.75</NB_HEURE> 
     <NOTES>foo</NOTES> 
     <CODE_TACHE>1234</CODE_TACHE> 
    </TACHE> 
</TACHES>