Jsp 复习材料一: XML解析

Jsp 复习材料一: XML解析

1.xml

1.规范:

  • 所有的XML文件都应该有结束标签
  • 便签大小写有区别,并且前后要一致
  • 规定XML只有一个根节点元素
  • 属性值必须加引号,可通过节点加getAttributes()。获得属性对象
  • 特殊字符需要转义
  • 解析时空格和回车换行会被保留

2.XML和HTML的差异

​ XML是对HTML的补充,即对数据进行存储和传输,可自行定义标签,不能通过浏览器显示,区别于HTML。

3.命名规范

  1. 名称可以含字母、数字以及其他的字符
  2. 名称不能以数字或者标点符号开始
  3. 名称不能以字符 “xml”(或者 XML、Xml)开始
  4. 名称不能包含空格
  5. 可使用任何名称,没有保留的字词
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE java1705 [
        <!ELEMENT java1705 (student+)>
        <!ELEMENT student (name,age,sex,height)>
        <!ATTLIST student id CDATA "10086">
        <!ATTLIST student user CDATA "jack">
        <!ELEMENT name (#PCDATA)>
        <!ELEMENT age (#PCDATA)>
        <!ELEMENT sex (#PCDATA)>
        <!ELEMENT height (#PCDATA)>
        ]>
//DTD约束
<java1705>
    <student id="1001" user="zhangsan">
        <name>张三</name>
        <age>19</age>
        <sex></sex>
        <height>180</height>
    </student>
    <student id="1002" user="lisi">
        <name>李四</name>
        <age>21</age>
        <sex></sex>
        <height>178</height>
    </student>
    <student id="1003" user="wangwu">
        <name>王五</name>
        <age>22</age>
        <sex></sex>
        <height>182</height>
    </student>
</java1705>

2.xml解析

2.1 DOM解析
1.特点

W3C认可的规范。适合于小型文件。基于树形结构。非一次性处理,简单。

2.代码:
public class DOM4jParse {
    public static void main(String[] args) {
        try {
            ///创建 XML 的DOM4J解析器
            SAXReader saxReader = new SAXReader();
            //解析XML文件
            Document document = saxReader.read(new File("student.xml"));
            //得到根节点
            Element rootElement = document.getRootElement();
            //得到根节点的所有子元素节点
            List<Element> elements = rootElement.elements();
            ArrayList<Student> list = new ArrayList<>();
            for (int i=0;i<elements.size();i++){
                Element element = elements.get(i);
                //获取属性值
                String id = element.attributeValue("id");//得到节点内队形属性名的值
                String user = element.attributeValue("user");
    //            Element name = element.element("name");//得到element节点下的name子元素子节点
    //            String text = name.getText();
                String name = element.elementText("name");//得到节点的内容
                String age = element.elementText("age");
                String sex = element.elementText("sex");
                String height = element.elementText("height");
                list.add(new Student(id,user,name,age,sex,height));
            }
            for (int i=0;i<list.size();i++){
                Student student = list.get(i);
                System.out.println(student.toString());
            }
        } catch (DocumentException e) {
            e.printStackTrace();
        }

    }
}
2.2 SAX解析
1.特点
  • 边读边解析,应用于大型XML文档
  • 解决内存问题,不需每次都访问内存
  • 事件驱动,文档读入过程就是SAX的解析过程,基于回调机制的程序运行方法
  • 只支持读、访问效率低、只能顺序访问
2.代码:
public class SAXParse {

    public static void main(String[] args) {
        try {
            //NO.1 创建解析工厂
            SAXParserFactory factory = SAXParserFactory.newInstance();
            //NO.2 通过解析工厂,创建解析构造器
            SAXParser saxParser = factory.newSAXParser();
            //No.3 指定解析的文件,并指定解析规则(DefaultHandler)
            MyHandler myHandler = new MyHandler();
            saxParser.parse(new File("student.xml"), myHandler);
            //解析结束
            ArrayList<Student> list = myHandler.getList();
            for (int i = 0; i < list.size(); i++) {
                Student student = list.get(i);
                System.out.println(student.toString());
            }
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * SAX 解析过程处理器
     */
    private static class MyHandler extends DefaultHandler {
        ArrayList<Student> list = new ArrayList<>();

        public ArrayList<Student> getList() {
            return list;
        }

        private Student student;

        @Override
        public void startDocument() throws SAXException {
            System.out.println("开始解析内容");
        }

        /**
         * 解析到开始标签
         *
         * @param uri        命名空间
         * @param localName  不支持
         * @param qName      [返回前缀:]标签名字(如果没有命名空间,返回标签名)
         * @param attributes 该标签的所有属性对象
         * @throws SAXException
         */
        @Override
        public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
//            System.out.println("<"+qName);
            if ("student".equals(qName)) {
                student = new Student();
                String id = attributes.getValue("id");
                String user = attributes.getValue("user");
                student.setId(Integer.parseInt(id));
                student.setUser(user);
            }
            target = qName;
        }

        //为了在characters方法中取出有效的字符内容,标记开始节点的名字
        private String target = null;

        /**
         * 解析到字符串内容(空格,回车,文字)
         *
         * @param ch     文档缓存在内存中的内容,长度为8192
         * @param start  遇到的文本内容在缓存中的位置,
         * @param length 文本内容到下一个元素节点的长度
         * @throws SAXException
         */
        @Override
        public void characters(char[] ch, int start, int length) throws SAXException {
            String content = new String(ch, start, length);
//            System.out.println(content);
            switch (target) {
                case "name":
                    student.setName(content);
                    break;
                case "age":
                    student.setAge(Integer.parseInt(content));
                    break;
                case "sex":
                    student.setSex(content);
                    break;
                case "height":
                    student.setHeight(content);
                    break;
            }
        }

        @Override
        public void endElement(String uri, String localName, String qName) throws SAXException {
            if ("student".equals(qName)) {
                list.add(student);
            }
            target = null;//为了防止结束节点之后取出的无效字符再次赋值给student,所以重置target
        }

        @Override
        public void endDocument() throws SAXException {
            System.out.println("解析结束");
        }
    }
}
2.3JDOM解析
1.特点
  • 基于树形结构,利用纯java技术对XML文档进行解析,它利用更为强有力的JAVA语言的诸多特性(方法重载、集合概念以及映射),把SAX和DOM的功能有效地结合起来。
  • 具有SAX的java规则
  • 没有向下兼容的限制,比DOM简单
  • 不过不能处理大于内存的文档。
  • 针对实例文档不提供DTD与模式的任何实际模型。
  • 不支持与DOM中相应遍历包
2.代码
public class JdomParse {
    public static void main(String[] args) {
        try {
            //NO.1 创建jDOM 解析构造器
            SAXBuilder saxBuilder = new SAXBuilder();
            //NO.2  解析整个XML文档
            org.jdom2.Document build = saxBuilder.build(new File("student.xml"));
            Element rootElement = build.getRootElement();//得到根节点
            List<Element> children = rootElement.getChildren();//获取元素节点下的所有子元素节点
            ArrayList<Student> list = new ArrayList<>();
            for(int i=0;i<children.size();i++){
                Element element = children.get(i);
                String id = element.getAttributeValue("id");
                String user = element.getAttributeValue("user");
                System.out.println("  "+id+"  "+user);

                //获取element元素下的name子元素节点
//                Element name = element.getChild("name");
//                String text = name.getText();//取出元素内容
                String name = element.getChildText("name");
                String age = element.getChildText("age");
                String sex = element.getChildText("sex");
                String height = element.getChildText("height");
                list.add(new Student(id,user,name,age,sex,height));
            }
            for (int i=0;i<list.size();i++){
                Student student = list.get(i);
                System.out.println(student.toString());
            }
        } catch (JDOMException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}
2.4DOM4j解析(重点掌握)

1.特点

  • 提供了构建文档表示的选项,它通过DOM4J API和标准DOM接口具有并行访问功能。
  • 使用Collections类,灵活
  • 一个简单、灵活的开放源代码的库、
  • 与JDOM不同的是,dom4j使用接口和抽象的人分离出来而后独立基类,虽然Dom4j的API相对要复杂一些,但它提供了比JDOM更好的灵活性。

2.代码

public class DOM4jParse {
    public static void main(String[] args) {
        try {
            ///创建 XML 的DOM4J解析器
            SAXReader saxReader = new SAXReader();
            //解析XML文件
            Document document = saxReader.read(new File("student.xml"));
            //得到根节点
            Element rootElement = document.getRootElement();
            //得到根节点的所有子元素节点
            List<Element> elements = rootElement.elements();
            ArrayList<Student> list = new ArrayList<>();
            for (int i=0;i<elements.size();i++){
                Element element = elements.get(i);
                //获取属性值
                String id = element.attributeValue("id");//得到节点内队形属性名的值
                String user = element.attributeValue("user");
    //            Element name = element.element("name");//得到element节点下的name子元素子节点
    //            String text = name.getText();
                String name = element.elementText("name");//得到节点的内容
                String age = element.elementText("age");
                String sex = element.elementText("sex");
                String height = element.elementText("height");
                list.add(new Student(id,user,name,age,sex,height));
            }
            for (int i=0;i<list.size();i++){
                Student student = list.get(i);
                System.out.println(student.toString());
            }
        } catch (DocumentException e) {
            e.printStackTrace();
        }

    }
}

3.比较

  1. DOM4J性能最好,连Sun的JAXM也在用DOM4J。目前许多开源项目中大量采用DOM4J,例如大名鼎鼎的Hibernate也用DOM4J来读取XML配置文件。如果不考虑可移植性,那就采用DOM4J.
  2. JDOM和DOM在性能测试时表现不佳,在测试10M文档时内存溢出。在小文档情况下还值得考虑使用DOM和JDOM。虽然JDOM的开发者已经说明他们期望在正式发行版前专注性能问题,但是从性能观点来看,它确实没有值得推荐之处。另外,DOM仍是一个非常好的选择。DOM实现广泛应用于多种编程语言。它还是许多其它与XML相关的标准的基础,因为它正式获得W3C推荐(与基于非标准的Java模型相对),所以在某些类型的项目中可能也需要它(如在JavaScript中使用DOM)。
  3. SAX表现较好,这要依赖于它特定的解析方式-事件驱动。一个SAX检测即将到来的XML流,但并没有载入到内存(当然当XML流被读入时,会有部分文档暂时隐藏在内存中)。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值