基于Dom4J实现XML快速解析(二)

XMLParse之XML文件解析实现

第一篇已经介绍了基础的XMLAttributeXMLBaseXMLNoChildsXMLHasKids四个类的设计,接下来我们根据上面四个类进行XML文件的解析。
提示,在解析XML时用到了第三方的dom4j.jar导入即可(站在巨人肩膀上真的很好)。

我们将XML文件的格式用JAVA类表示出来
举例:

<Books type="文艺">
    <Book name="西游记"/>
    <Book name="红楼梦"/>
</Books>

我们用JAVA这样描述:

class Book{
    private String name;
    //构造方法和get set
}
class Books{
    private String type;
    private List<Book> books;
    //构造方法和get set
    //注意,在构造方法中要实现books的实例化
}

这两种类称为XML标签类
将这两个XML标签类放到指定位置就可以通过反射找到他们,然后在调用transform()进行转换

XML解析过程

XML解析过程:读取文件、生成XMLBase、调用transform()转化。

读取文件

通过dom4j.jar进行读取,本人用的是SAXReader来进行读取。

生成XMLBase

XMLReader.java中定义了XMLparse()方法,其中用到了递归处理,因为子标签也可能有子标签,递归结束标志就是当前标签是无子标签。

public static void XMLparse(Element rootElement,XMLBase root){
        XMLBase cur;
        //判断标签元素是否还有子元素
        if (rootElement.elements().size()>0){
            //含有子元素,创建XMLBase
            cur = new XMLHasKids(rootElement.getName());
            //给XMLBase中的属性集合赋值
            List<Attribute> attributes = rootElement.attributes();
            List<XMLAttribute> xmlAttributes = new ArrayList<>();
            for (Attribute attribute : attributes) {
                xmlAttributes.add(new XMLAttribute(attribute.getName(),attribute.getValue()));
            }
            cur.setXMLAttributes(xmlAttributes);
            //将新创建的XMLBase添加到上一级的子标签集合中
            root.addKids(cur);
            //对子元素的子元素进行递归赋值
            List<Element> childelement = rootElement.elements();
            for (Element element : childelement) {
                XMLparse(element,cur);
            }
        }else {
            //当没有子元素时,创建XMLBase对象
            cur = new XMLNoChilds(rootElement.getName());
            //给XMLBase对象中的属性集合赋值
            List<Attribute> attributes = rootElement.attributes();
            List<XMLAttribute> xmlAttributes = new ArrayList<>();
            for (Attribute attribute : attributes) {
                xmlAttributes.add(new XMLAttribute(attribute.getName(),attribute.getValue()));
            }
            cur.setXMLAttributes(xmlAttributes);
            //将新创建的XMLBase添加到上一级的子标签集合中
            root.addKids(cur);
        }
    }
transform转换

对于已经生成XMLBase的XML文件,只需要调用XMLBase的transform()方法就能获得对应的XML标签类实例。此方法已经封装到了XMLAPI.java中。

    /**
     * Read xml object.
     *
     * @param inputStream the input stream of xml file
     * @return the object
     */
    public static Object readXML(InputStream inputStream){
        Element rootElement = null;
        SAXReader reader = new SAXReader();
        try {
            document = reader.read(inputStream);
        } catch (DocumentException e) {
            e.printStackTrace();
        }
        //先 将root 节点解析出来
        if (document != null)rootElement = document.getRootElement();
        XMLBase root = new XMLHasKids(rootElement.getName());
        List<Attribute> attributes = rootElement.attributes();
        List<XMLAttribute> xmlAttributes = new ArrayList<>();
        for (Attribute attribute : attributes) {
            xmlAttributes.add(new XMLAttribute(attribute.getName(),attribute.getValue()));
        }
        root.setXMLAttributes(xmlAttributes);

        //利用递归 将子节点逐一解析 放入xmlbase 中
        List<Element> childelement = rootElement.elements();
        for (Element element : childelement) {
            XmlReader.XMLparse(element,root);
        }

        return root.transform();
    }

返回的是Object对象,直接强转即可。到此XML解析设计结束。下一篇我们研究XML文件的生成。

最后说一下,上一篇中XMLBase抽象类中是定义了一个方法valueFormat()是在transform()时对属性进行赋值的,现在贴出来,当然还有很多需要优化的地方。

    /**
     *数值转换方法,根据不同的数值类型将值传入
     *关键是异常捕获后的赋值,避免赋值出现空值
     */
    protected void valueFormat(String type,Object o,XMLAttribute XMLAttribute,Method method) throws InvocationTargetException, IllegalAccessException {
        if (type.contains(".String")){
            method.invoke(o,XMLAttribute.getValues());
        }else if (type.contains(".Integer")){
            Integer values;
            try {
                values = Integer.valueOf(XMLAttribute.getValues());
            }catch (NumberFormatException e){
                e.printStackTrace();
                values = 0;
            }
            method.invoke(o,values);
        }else if (type.contains(".Float")){
            Float values;
            try {
                values = Float.valueOf(XMLAttribute.getValues());
            }catch (NumberFormatException e){
                values = 0.0f;
                e.printStackTrace();
            }
            method.invoke(o,values);
        }else if(type.contains(".Boolean")){
            Boolean values;
            values = Boolean.valueOf(XMLAttribute.getValues());
            method.invoke(o,values);
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值