1. 程式人生 > >JAVA物件轉換成XML()

JAVA物件轉換成XML()

編者小結:將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  由於總結過程實屬不易如需轉載請註明出處,謝謝!