JAVA物件轉換成XML()
阿新 • • 發佈:2019-02-19
編者小結:將java物件轉換成xml檔案很簡單,但是將java物件轉換成<![CDATA[文字內容]]>輸出結果不轉義的形式就相當不易。大家都知道在XML 元素中,"<" 和 "&" 是非法的。"<" 會產生錯誤,因為解析器會把該字元解釋為新元素的開始。"&" 也會產生錯誤,因為解析器會把該字元解釋為字元實體的開始。某些文字,比如 JavaScript 程式碼,包含大量 "<" 或"&" 字元。為了避免錯誤,可以將指令碼程式碼定義為 CDATA。
CDATA:在標記CDATA下,所有的標記、實體引用都被忽略,而被XML處理程式一視同仁地當作字元資料看待,CDATA的形式如下:
<![CDATA[文字內容]]>
CDATA的文字內容中不能出現字串“]]>”,另外,CDATA不能巢狀。
具體實現過程如下:
Java實體類:
publicclassJavaDocu { privateintid; private String text; publicint getId() { returnid; } publicvoid setId(int id) { this.id = id; } public String getText() { returntext; } publicvoid setText(String text) { this.text = text; } }
MyXppDriver類:
publicclassMyXppDriver extends XppDriver {
public HierarchicalStreamWritercreateWriter(Writer out){
returnnew MyPrettyPrintWriter(out);
}
}
MyPrettyPrintWriter類:
publicclassMyPrettyPrintWriterimplementsExtendedHierarchicalStreamWriter { privatefinal QuickWriter writer; privatefinal FastStack elementStack = new FastStack(16); privatefinalchar[] lineIndenter; privatebooleantagInProgress; privateintdepth; privatebooleanreadyForNewLine; privatebooleantagIsEmpty; privatestaticfinalchar[] AMP = "&".toCharArray(); privatestaticfinalchar[] LT = "<".toCharArray(); privatestaticfinalchar[] GT = ">".toCharArray(); privatestaticfinalchar[] SLASH_R = " ".toCharArray(); privatestaticfinalchar[] QUOT = """.toCharArray(); privatestaticfinalchar[] APOS = "'".toCharArray(); privatestaticfinalchar[] CLOSE = "</".toCharArray(); publicMyPrettyPrintWriter(Writer writer, char[] lineIndenter) { this.writer = new QuickWriter(writer); this.lineIndenter = lineIndenter; } publicMyPrettyPrintWriter(Writer writer, String lineIndenter) { this(writer,lineIndenter.toCharArray()); } public MyPrettyPrintWriter(PrintWriterwriter) { this(writer, newchar[] { ' ', ' ' }); } publicMyPrettyPrintWriter(Writer writer) { this(new PrintWriter(writer)); } @Override publicvoid addAttribute(Stringkey, String value) { writer.write(' '); writer.write(key); writer.write('='); writer.write('\"'); writeAttributeValue(writer, value); writer.write('\"'); } protectedvoidwriteAttributeValue(QuickWriter writer, String text) { int length = text.length(); for (int i = 0; i < length;i++) { char c = text.charAt(i); switch (c) { case'&': this.writer.write(AMP); break; case'<': this.writer.write(LT); break; case'>': this.writer.write(GT); break; case'"': this.writer.write(QUOT); break; case'\'': this.writer.write(APOS); break; case'\r': this.writer.write(SLASH_R); break; default: this.writer.write(c); } } } @Override publicvoid endNode() { depth--; if (tagIsEmpty) { writer.write('/'); readyForNewLine = false; finishTag(); elementStack.popSilently(); }else{ finishTag(); writer.write(CLOSE); writer.write((String) elementStack.pop()); writer.write('>'); } readyForNewLine = true; if (depth == 0) { writer.flush(); } } @Override publicvoid setValue(String text) { readyForNewLine = false; tagIsEmpty = false; finishTag(); writeText(writer, text); } protectedvoid writeText(QuickWriterwriter, String text) { int length = text.length(); StringCDATAPrefix = "<![CDATA["; if(!text.startsWith(CDATAPrefix)) { for (int i = 0; i < length;i++) { char c = text.charAt(i); switch (c) { case'&': this.writer.write(AMP); break; case'<': this.writer.write(LT); break; case'>': this.writer.write(GT); break; case'"': this.writer.write(QUOT); break; case'\'': this.writer.write(APOS); break; case'\r': this.writer.write(SLASH_R); break; default: this.writer.write(c); } } } else { for (int i = 0; i < length;i++) { char c = text.charAt(i); this.writer.write(c); } } } @Override publicvoid startNode(String name){ tagIsEmpty = false; finishTag(); writer.write('<'); writer.write(name); elementStack.push(name); tagInProgress = true; depth++; readyForNewLine = true; tagIsEmpty = true; } privatevoid finishTag() { if (tagInProgress) { writer.write('>'); } tagInProgress = false; if (readyForNewLine) { endOfLine(); } readyForNewLine = false; tagIsEmpty = false; } protectedvoid endOfLine() { writer.write('\n'); for (int i = 0; i < depth; i++) { writer.write(lineIndenter); } } publicvoid flush() { writer.flush(); } publicvoid close() { writer.close(); } @Override publicHierarchicalStreamWriter underlyingWriter() { returnthis; } @Override publicvoid startNode(String name, @SuppressWarnings("rawtypes")Class arg1) { // TODO Auto-generated method stub tagIsEmpty = false; finishTag(); writer.write('<'); writer.write(name); elementStack.push(name); tagInProgress = true; depth++; readyForNewLine = true; tagIsEmpty = true; } }
Java測試類:
publicclassJavaDocuTest {
publicstaticvoid main(String[] args) throws IOException,JAXBException {
Long t1 = System.currentTimeMillis();
StringCDATAPrefix = "<![CDATA[";
StringCDATABackfix = "]]>";
JavaDocujavadocu = newJavaDocu();
JavaDocujavadocu2 = newJavaDocu();
javadocu.setText(CDATAPrefix+ "這是一個測試" + CDATABackfix);
javadocu2.setText(CDATAPrefix+ "這又是一個測試" + CDATABackfix);
List<JavaDocu>list = newArrayList<JavaDocu>();
list.add(javadocu);
list.add(javadocu2);
XStreamxstream = newXStream(newMyXppDriver());
for (int i = 0; i <list.size(); i++) {
list.get(i).setId(i);
xstream.alias("javatoxml",JavaDocu.class);
xstream.useAttributeFor(JavaDocu.class, "id");
// xstream.useAttributeFor("id",String.class);
}
System.out.println(xstream.toXML(list));
xstream.toXML(list, new PrintWriter("c:\\測試.xml", "utf-8"));
}
}
以上程式碼可實現將javabean轉換成包含<![CDATA[文字內容]]>的xml檔案。
本文原創yhcz 由於總結過程實屬不易如需轉載請註明出處,謝謝!