阅读 69

xml解析

 

XML解析

1、XML概述

  • XML 指可扩展标记语言(EXtensible Markup Language)

  • XML 是一种标记语言,很类似 HTML

  • XML 的设计宗旨是传输数据,而非显示数据

  • XML 标签没有被预定义。您需要自行定义标签

  • XML 被设计为具有自我描述性

  • XML 是 W3C 的推荐标准

2、XML组成

2.1、标签

  1. 标签是由尖括号 包围的关键词,比如

  2. 标签通常是成对出现 的,比如

     
  3. 标签对中的第一个标签是开始标签 ,第二个标签是结束标签 ,开始和结束标签也被称为开放标签闭合标签

  4. 空标签 由 一些标签没有内容,可以用一个标签来表示,比如setting标签

    
            
            
            
    

2.2、属性

标签可以拥有属性 。属性提供了有关 HTML 元素的更多的信息

属性总是以名称/值对的形式出现,比如:name="value"

属性总是在 HTML 元素的开始标签 中规定。

实例如下

This is a link

2.3、文本内容

在开始标签与结束标签中可以存放文本内容

2.4、XML 元素

xml元素指的是从(且包括)开始标签直到(且包括)结束标签的部分。

2.5、XML 文档形成一种树结构

下面的 XML 文档表示书店中有的书



  Everyday Italian 
  Giada De Laurentiis 
  2005 
  30.00 


  Harry Potter 
  J K. Rowling 
  2005 
  29.99 


  Learning XML 
  Erik T. Ray 
  2003 
  39.95 

上述XML文档可以表示成一个树形结构

 

3、xml基础语法

  1. XML 文档必须包含根元素 。该元素是所有其他元素的父元素。

  2. 所有 XML 元素都须有关闭标签。

  3. XML 标签对大小写敏感

  4. XML 的属性值须加引号

  5. XML 必须正确地嵌套

  6. 实体引用

    在 XML 中,一些字符拥有特殊的意义。

    如果你把字符 "<" 放在 XML 元素中,会发生错误,这是因为解析器会把它当作新元素的开始。

    这样会产生 XML 错误

    if salary < 1000 then

    为了避免这个错误,请用实体引用 来代替 "<" 字符:

    if salary < 1000 then 

    在 XML 中,有 5 个预定义的实体引用:

    &lt; < 小于
    &gt; > 大于
    &amp; &
    &apos; 单引号
    &quot; " 引号
  7. XML 中的注释

    在 XML 中编写注释的语法与 HTML 的语法很相似:

  8. 在 XML 中,空格会被保留

    HTML 会把多个连续的空格字符裁减(合并)为一个:

    HTML:   Hello           my name is David.
    输出: Hello my name is David.
    ?

    在 XML 中,文档中的空格不会被删节。

  9. xml文档声明

    一个 XML 文档实例



    George
    John
    Reminder
    Don‘t forget the meeting!

 

第一行:

语法要求<,?,xml之间不能有空格, ?>之间不能有空格,standalone="no"?两者之间可以有一个或多个空格。

encoding=”utf-8”:那么解析器读到该属性,那么会以utf-8解码,如果不写呢?XML解析器通过寻找XML文档开始处的字节序列,能够自动检测出文档中的Unicode编码是UTF-8还是UTF-16.也就是说encoding属性的默认值是Unicode编码,如果文档是以UTF-8/UTF-16编码那么可以不设置该属性.

standalone属性用于说明文档是否独立(该文档没有依赖外面的任何文件而可以单独存在(例如依赖dtd文件) 所以值是yes,)。独立的文档是yes, 依赖外部文件的文档是no。standalone属性位于encoding属性之后。

 

4、XML文档解析

XML的解析方式分为两种:1、DOM解析;2、SAX解析

4.1、DOM解析

**DOM的全称是Document Object Model,也即文档对象模型。在应用程序中,基于DOM的XML分析器将一个XML文档转换成一个对象模型的集合(通常称DOM树),应用程序正是通过对这个对象模型的操作,来实现对XML文档数据的操作。通过DOM接口,应用程序可以在任何时候访问XML文档中的任何一部分数据,因此,这种利用DOM接口的机制也被称作随机访问机制。** 
?
**DOM接口提供了一种通过分层对象模型来访问XML文档信息的方式,这些分层对象模型依据XML的文档结构形成了一棵节点树。无论XML文档中所描述的是什么类型的信息,即便是制表数据、项目列表或一个文档,利用DOM所生成的模型都是节点树的形式。也就是说,DOM强制使用树模型来访问XML文档中的信息。由于XML本质上就是一种分层结构,所以这种描述方法是相当有效的。**

 

  DOM树所提供的随机访问方式给应用程序的开发带来了很大的灵活性,它可以任意地控制整个XML文档中的内容。然而,由于DOM分析器把整个XML文档转化成DOM树放在了内存中,因此,当文档比较大或者结构比较复杂时,对内存的需求就比较高。而且,对于结构复杂的树的遍历也是一项耗时的操作。所以,DOM分析器对机器性能的要求比较高,实现效率不十分理想。不过,由于DOM分析器所采用的树结构的思想与XML文档的结构相吻合,同时鉴于随机访问所带来的方便,因此,DOM分析器还是有很广泛的使用价值的。

优点:

1、形成了树结构,有助于更好的理解、掌握,且代码容易编写。

2、解析过程中,树结构保存在内存中,方便修改。

缺点:

1、由于文件是一次性读取,所以对内存的耗费比较大。

2、如果XML文件比较大,容易影响解析性能且可能会造成内存溢出。

xml实例



    
        冰与火之歌
        乔治马丁
        2014
        89
    
    
        安徒生童话
        2004
        77
        English
        

?
public class DOMTest {
    public static void main(String[] args) {
        //创建一个DocumentBuilderFactory的对象
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        //创建一个DocumentBuilder的对象
        try {
            //创建DocumentBuilder对象
            DocumentBuilder db = dbf.newDocumentBuilder();
            //通过DocumentBuilder对象的parser方法加载books.xml文件到当前项目下
            Document document = db.parse("books.xml");
            //获取所有book节点的集合
            NodeList bookList = document.getElementsByTagName("book");
            //通过nodelist的getLength()方法可以获取bookList的长度
            System.out.println("一共有" + bookList.getLength() + "本书");
            //遍历每一个book节点
            for (int i = 0; i < bookList.getLength(); i++) {
                System.out.println("=================下面开始遍历第" + (i + 1) + "本书的内容=================");
                //通过 item(i)方法 获取一个book节点,nodelist的索引值从0开始
                Node book = bookList.item(i);
                //获取book节点的所有属性集合
                NamedNodeMap attrs = book.getAttributes();
                System.out.println("第 " + (i + 1) + "本书共有" + attrs.getLength() + "个属性");
                //遍历book的属性
                for (int j = 0; j < attrs.getLength(); j++) {
                    //通过item(index)方法获取book节点的某一个属性
                    Node attr = attrs.item(j);
                    //获取属性名
                    System.out.print("属性名:" + attr.getNodeName());
                    //获取属性值
                    System.out.println("--属性值" + attr.getNodeValue());
                }
                //解析book节点的子节点
                NodeList childNodes = book.getChildNodes();
                //遍历childNodes获取每个节点的节点名和节点值
                System.out.println("第" + (i+1) + "本书共有" + 
                childNodes.getLength() + "个子节点");
                for (int k = 0; k < childNodes.getLength(); k++) {
                    //区分出text类型的node以及element类型的node
                    if (childNodes.item(k).getNodeType() == Node.ELEMENT_NODE) {
                        //获取了element类型节点的节点名
                        System.out.print("第" + (k + 1) + "个节点的节点名:" 
                        + childNodes.item(k).getNodeName());
                        //获取了element类型节点的节点值
                        System.out.println("--节点值是:" + childNodes.item(k).getFirstChild().getNodeValue());
                        //System.out.println("--节点值是:" + childNodes.item(k).getTextContent());
                    }
                }
                System.out.println("======================结束遍历第" + (i + 1) + "本书的内容=================");
            }
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }        
    }
}
?

上述代码把XML解析成Document ,对XML元素的访问太过麻烦,还有一种通过XPaht方式的访问方式,在Mybatis中也是采取这种方式

实例如下



    
        张三
        2018-06-06 00:00:00
        admin
        180000000
        阿毛
    
    
        李四
        2018-06-06 00:00:00
        admin
        180000001
        明明
    

?

xml对应的java类

package com.blog4java.mybatis.xpath;
?
import lombok.Data;
?
import java.util.Date;
?
@Data
public class UserEntity {
    private Long id;
    private String name;
    private Date createTime;
    private String password;
    private String phone;
    private String nickName;
}
?

java解析代码

package com.blog4java.mybatis.xpath;
?
import com.alibaba.fastjson.JSON;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.converters.DateConverter;
import org.apache.ibatis.builder.BuilderException;
import org.apache.ibatis.io.Resources;
import org.junit.Test;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
?
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
?
public class XPathExample {
?
    @Test
    public void testXPathParser() {
        try {
            // 创建DocumentBuilderFactory实例    Jdk内部的类
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            // 创建DocumentBuilder实例
            DocumentBuilder builder = factory.newDocumentBuilder();
            InputStream inputSource = Resources.getResourceAsStream("users.xml");
            Document doc = builder.parse(inputSource);
            // 获取XPath实例    Jdk内部的类
            XPath xpath = XPathFactory.newInstance().newXPath();
            // 执行XPath表达式,获取节点信息
            NodeList nodeList = (NodeList)xpath.evaluate("/users/*", doc, XPathConstants.NODESET);
            List userList = new ArrayList<>();
            for(int i=1; i < nodeList.getLength() + 1; i++) {
                String path = "/users/user["+i+"]";
                String id = (String)xpath.evaluate(path + "/@id", doc, XPathConstants.STRING);
                String name = (String)xpath.evaluate(path + "/name", doc, XPathConstants.STRING);
                String createTime = (String)xpath.evaluate(path + "/createTime", doc, XPathConstants.STRING);
                String passward = (String)xpath.evaluate(path + "/passward", doc, XPathConstants.STRING);
                String phone = (String)xpath.evaluate(path + "/phone", doc, XPathConstants.STRING);
                String nickName = (String)xpath.evaluate(path + "/nickName", doc, XPathConstants.STRING);
                // 调用buildUserEntity()方法,构建UserEntity对象
                UserEntity userEntity = buildUserEntity(id,name, createTime, passward, phone, nickName);
                userList.add(userEntity);
            }
            System.out.println(JSON.toJSONString(userList));
        } catch (Exception e) {
            throw new BuilderException("Error creating document instance.  Cause: " + e, e);
        }
    }
?
    private UserEntity buildUserEntity(String id,String name,
                                       String createTime, String passward,
                                       String phone, String nickName)
            throws IllegalAccessException, InvocationTargetException {
        UserEntity userEntity = new UserEntity();
        DateConverter dateConverter = new DateConverter(null);
        dateConverter.setPattern("yyyy-MM-dd HH:mm:ss");
        ConvertUtils.register(dateConverter,Date.class);
        BeanUtils.setProperty(userEntity,"id",id);
        BeanUtils.setProperty(userEntity,"name",name);
        BeanUtils.setProperty(userEntity,"createTime",createTime);
        BeanUtils.setProperty(userEntity,"passward",passward);
        BeanUtils.setProperty(userEntity,"phone",phone);
        BeanUtils.setProperty(userEntity,"nickName",nickName);
        return userEntity;
    }
}
?

原文:https://www.cnblogs.com/cplinux/p/15310283.html

文章分类
代码人生
文章标签
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐