Android XStream parses xml data into bean s to support CDATA

Keywords: Android xml Retrofit Gradle

Reference resources

1,Android parses complex xml into javabean using XStream
2,XStream supports CDATA Tags
3,Retrofit Accesses Web Service with Soap Protocol

Example

Keep the previous retrofit article after accessing web service, and finally until the access is successful, until the CDATA data needs to be parsed, continue the following work, first look at the data format bar:

 * CDATA Specific data
 <![CDATA[
 <updatedata>
    <table>
        <name>table_xxx</name>
        <field>id, codeid, name, pid, remark, inputdate, modifydate, status, type_num</field>
        <values>
            <value>302|302|nitrite|1|Testing items|2016-08-24 10:58:51.0|null|C|null</value>
            ...
            <value>472|472|Amino nitrogen in soy sauce|1|Testing items|2016-08-24 10:58:51.0|null|C|null</value>
        </values>
    </table>-200

    <table>
        <name>table_yyy</name>
        <field>id, inputdate, modifydate, decision_basis, max_limit, min_limit, test_basis, unit, food_type, test_item</field>
        <values>
            ....
        </values>
    </table>
 </updatedata>
 ]]>

OK It also needs sharp tools to parse, XStream to come (other SAX-xml, JSoup-html should also be able to)

1. build.gradle under app, add dependencies
    compile ('com.thoughtworks.xstream:xstream:1.4.7') {
        exclude group: 'xmlpull', module: 'xmlpull'
    }
2. Establishment of xml bean s
2.1, @XStreamAlias root node
2.2, @XStreamImplicit subnode
2.3 Explanation: (1) If the child node is a value, it can be obtained directly by String xxSameAsElementName (2). If there are child nodes in the child node, it can be obtained by bean. The name of the child node can be the same. Different Element should be annotated (3). If the child node has N identical words, it can be obtained by List < Bean > and annotated by the child node.

1. Layer 1: updatedata is the root node, with table s and multiple sub-nodes, using list < bean >
2. Layer 2: There is only one single element under the table. If it is a value, it can be obtained directly by string xxSameAsElment. If there are nodes, it can be used by bean s.
3. Layer 3: There are N identical data, annotate sub-nodes, and use List < String > to obtain them.

@XStreamAlias("updatedata")//Class annotations (must be written), root nodes
public class ZydUpdateDataBean {

    @XStreamImplicit(itemFieldName = "table")//Node annotations (must be written), N with List
    private List<ZydTableBean> tables;

    public List<ZydTableBean> getTables() {
        return tables;
    }

    public void setTables(List<ZydTableBean> tables) {
        this.tables = tables;
    }

    //2: You can see three elements under each table
    public static class ZydTableBean{
        String name;
        String field;
        ZydValues values;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getField() {
            return field;
        }

        public void setField(String field) {
            this.field = field;
        }

        public ZydValues getValues() {
            return values;
        }

        public void setValues(ZydValues values) {
            this.values = values;
        }

        //3
        public static class ZydValues{
            @XStreamImplicit(itemFieldName = "value")//Node annotations (must be written)
            private List<String> valueList;

            public List<String> getValueList() {
                return valueList;
            }

            public void setValueList(List<String> valueList) {
                this.valueList = valueList;
            }
        }
    }
}
3. XStream Tool for CDATA ~~Direct Copy
public class XStreamUtil {
    public static String PREFIX_CDATA = "<![CDATA[";
    public static String SUFFIX_CDATA = "]]>";

    /**
     * Full transformation
     */
    public static XStream initXStream() {
        return new XStream(new XppDriver() {
            @Override
            public HierarchicalStreamWriter createWriter(Writer out) {
                return new PrettyPrintWriter(out) {
                    protected void writeText(QuickWriter writer, String text) {
                        // if (text.startsWith(PREFIX_CDATA) &&
                        // text.endsWith(SUFFIX_CDATA)) {
                        writer.write(PREFIX_CDATA + text + SUFFIX_CDATA);
                        // } else {
                        // super.writeText(writer, text);
                        // }
                    }
                };
            }
        });
    }

    /**
     * Initialization of XStream allows a field to be tagged with CDATA, and if a field is required to use the original text, it needs to be added to the head of a text of String type.
     * "<![CDATA["Add a "]>" tag at the end for identification when XStream outputs
     * @param isAddCDATA Whether CDATA tags are supported or not
     */
    public static XStream initXStream(boolean isAddCDATA) {
        XStream xstream = null;
        if (isAddCDATA) {
            xstream = new XStream(new XppDriver() {
                @Override
                public HierarchicalStreamWriter createWriter(Writer out) {
                    return new PrettyPrintWriter(out) {
                        protected void writeText(QuickWriter writer, String text) {
                            if (text.startsWith(PREFIX_CDATA) && text.endsWith(SUFFIX_CDATA)) {
                                writer.write(text);
                            } else {
                                super.writeText(writer, text);
                            }
                        }
                    };
                }
            });
        } else {
            xstream = new XStream();
        }
        return xstream;
    }
}
4. Specific Analysis
//Get rid of clutter
updateData = updateData.replace("</table>-200","</table>");
//XStream parser: XML - > bean
boolean flag = updateData.contains(XStreamUtil.PREFIX_CDATA);
XStream xStream = XStreamUtil.initXStream(flag);
xStream.processAnnotations(ZydUpdateDataBean.class);
ZydUpdateDataBean dataBean = (ZydUpdateDataBean) xStream.fromXML(updateData);

Posted by dniezby on Tue, 22 Jan 2019 21:57:13 -0800