XML

主要介绍解析XML的两种方式

DOM4J解析:面向对象,由于是一次性读取整个文档到内存中,读取大文件的时候可能会造成内存占用过多。
SAX解析:基于事件,一次读取一部分,操作上比DOM4J繁琐一点,不会造成内存占用问题。

DOM 解析 SAX 解析
原理 一次性加载,内存占用比较大 加载一点,读取一点,内存占用小
读取顺序 可以任意读取,可以往回读 只能从上往下依次读取,不能往回读
操作方式 可查询,也可修改 只能查询
编码方式 面向对象 基于事件

大纲

  1. DOM4J 解析
    1. 导包
    2. 核心类和方法
    3. 读取XML
    4. 写出XML
    5. XPath
  2. SAX 解析 jdk集成
    1. 核心类
    2. 读取XML文件加载对象到容器 DEMO

#DOM4J 解析

dom4j是一个Java的XML API,是jdom的升级品,用来读写XML文件的。dom4j是一个十分优秀的JavaXML API,具有性能优异、功能强大和极其易使用的特点,它的性能超过sun公司官方的dom技术,同时它也是一个开放源代码的工具。


##导包 下载JAR包
  • dom4j-1.6.1.jar

##核心类和方法

SAXReader:负责XML文件的加载
XMLWriter:负责XML文件的输出
DocumentHelper:用来生成生成 XML 文档的工厂类
Element:元素节点

三个重要概念:标签、属性、文本

  • 标签 Element
Method Method Description
getRootElement() 得到文档根元素
addElement("name") 添加子标签
element("name") 寻找指定标签名的子元素
elements("names") 寻找指定标签名的子元素(全部)
elements() 寻找全部子元素
  • 属性 Atrribute
Method Method Description
atrributeValue("name") 得到指定属性的值
addAtribute("name", "value") 添加属性(以存在则修改)
atrribute("name") 得到属性对象
atrributes() 全部属性对象列表
getName() 得到属性名
getValue() 得到属性值
  • 文本
Method Method Description
getText() 得到文本信息
setText() 修改文本信息
elementText("name") 得到子标签的文本信息
  • 其他

DocumentHelper.createDocument():创建新文档
detach():标签/属性 自杀
getParent().remove(标签/属性):调用父类的删除方法来删除标签/属性


##读取XML
/**
 * loading XML File Resource
 * @param path XML Resource File Path
 * @return XML Document Object
 */
public static Document reader(String path) {
    Document document = null;
    try {
        return new SAXReader().read(XMLTools.class.getClassLoader().getResourceAsStream(path));
    } catch (DocumentException e) {
        e.printStackTrace();
    }
        return document;
}

Document read(File file)
Document read(URL url)
Document read(String systemId)
Document read(InputStream in)
Document read(Reader reader)

##写出XML
/**
 * Writer XML File Resource
 * @param document XML Document Object
 * @param path XML Resource File Path
 * @return result
 */
public static boolean writer(Document document, String path) {
    boolean flag = true;
    try {
        OutputFormat format = OutputFormat.createPrettyPrint();
        format.setEncoding("UTF-8");
        XMLWriter writer = new XMLWriter(
            new FileWriter(XMLTools.class.getClassLoader().getResource(path).getPath()),
            format
        );

        writer.write(document);
        writer.close();
    } catch (Exception e) {
        flag = false;
        e.printStackTrace();
    }
    return flag;
}

##XPath XPath语法
  • 导包:jaxen-1.1-beta-6.jar
// 搜索多个节点
List<Node> nodes = document.selectNodes(XPath表达式);
// 搜索单个节点
Node node = document.selectSingleNode(XPath表达式);

#SAX 解析 jdk集成

SAX,全称Simple API for XML,既是一种接口,也是一种软件包。它是一种XML解析的替代方法。SAX不同于DOM解析,它逐行扫描文档,一边扫描一边解析。由于应用程序只是在读取数据时检查数据,因此不需要将数据存储在内存中,这对于大型文档的解析是个巨大优势。


##核心类

SAXParser:负责解析XML
DefaultHandler:负责监听加载XML触发的事件

  • DefaultHandler 自定义一个类继承DefaultHandler类
    • startDocument():文档开始
    • endDocument():文档结束
    • startElement():元素开始
    • endElement():元素结束
    • characters():文本 当前元素的 text 加载完
##读取XML配置加载对象到容器

下面是一个读取XML文件,通过反射技术生成对象并存放到容器的Demo

LoadObjectHandler.java

/**
 * 读取XML文件加载对象到容器
 */
public class LoadObjectHandler extends DefaultHandler {
    public static final String BEAN_NODE = "bean";
    public static final String BEAN_NAME = "name";
    public static final String BEAN_CLASS = "class";

    // Object Container
    private Map<String, Object> container = new HashMap<>();

    /**
     * 元素开始
     *
     * @param uri
     * @param localName
     * @param qName      标签名
     * @param attributes 属性列表
     * @throws SAXException
     */
    @Override
    public void startElement(String uri, String localName, String qName,
                             Attributes attributes) throws SAXException {

        if (qName != null && qName.equals(BEAN_NODE)) {
            if (attributes != null) {
                for (int i = 0; i < attributes.getLength(); i++) {
                    String name = attributes.getValue(BEAN_NAME);
                    String clazz = attributes.getValue(BEAN_CLASS);

                    try {
                        Class<?> mClass = getClass().forName(clazz);
                        Object obj = mClass.newInstance();
                        container.put(name, obj);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    /**
     * 从容器返回对象
     *
     * @param name Object key
     * @return Object
     */
    public Object getObject(String name) {
        return container.get(name);
    }
}

test.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans>
    <bean name="User" class="tools.xml.test1.User"/>
</beans>

App.java

String path = "../resource/test.xml";

// 从工厂得到解析器
SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
// 创建自定义监听器对象
LoadObjectHandler handler = new LoadObjectHandler();
// 解析XML文件
parser.parse(new File(XMLTools.class.getResource(path).getPath()), handler);
System.out.println(handler.getObject("User"));

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,014评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,796评论 3 386
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,484评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,830评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,946评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,114评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,182评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,927评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,369评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,678评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,832评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,533评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,166评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,885评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,128评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,659评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,738评论 2 351