看了“罗辑思维”的节目,终于克服了自己的拖延症,开始动笔写这篇文章了。

写这篇文章的目的是把XML的解析,萃取和验证都尽量覆盖一下,存储以便日后备考,使用的包是dom4j,涉及语言是Java。

dom4j解析XML使用的包是dom4j-1.6.1.jar,你可以从 http://pan.baidu.com/s/1GedS6 下载。

另外,如果要使用XPath,还需要用到jaxen-1.1-beta-9.jar,你可以从 http://pan.baidu.com/s/1GKb7h 下载。

下文程序也是用到这两个包。

1.XML之解析

解析XML基本的操作就是先找到document,再找到根节点,再从根节点一层一层往下走。

先看一个解析XML文件获取信息的例子:

1.1 从文件解析XML

XML文件内容如下:(能有此整齐划一的效果多亏Eclipse的Source->Format工具,要是Notepad++和Editplus也纳入这个功能就好了)

<?xml version="1.0" encoding="UTF-8"?>
<words>
    <word>
        <id>1</id>
        <sl>en-US</sl>
        <tl>zh-CN</tl>
        <txt status="ok"><![CDATA[Prevention of dengue fever. Grenada dengue cases show multiple recently and the trend of virus mutation, increased risk]]></txt>
    </word>
    <word>
        <id>2</id>
        <sl>zh-CN</sl>
        <tl>en-US</tl>
        <txt status="ok"><![CDATA[预防登革热。最近格林纳达登革热病例显示多个和病毒变异的趋势,增加的风险]]></txt>
    </word>
    <word>
        <id>3</id>
        <sl>zh-CN</sl>
        <tl>en-US</tl>
        <txt status="ok"><![CDATA[天天向上]]></txt>
    </word>
</words>

解析程序如下:

        SAXReader reader = new SAXReader();
        InputStream is = new FileInputStream("C:\\Users\\IBM_ADMIN\\Desktop\\1.xml");
        org.dom4j.Document doc = reader.read(is);  

        Element rootElt = doc.getRootElement();
        Iterator<Element> iter = rootElt.elementIterator("word");

        while (iter.hasNext()) {
            Element wordElm = (Element) iter.next();

            String id = wordElm.elementTextTrim("id");
            String txt = wordElm.elementTextTrim("txt");
            String status=wordElm.element("txt").attributeValue("status");

            System.out.println("id="+id+" txt="+txt+" status="+status);
        }

控制台输出如下:

id=1 txt=Prevention of dengue fever. Grenada dengue cases show multiple recently and the trend of virus mutation, increased risk status=ok
id=2 txt=预防登革热。最近格林纳达登革热病例显示多个和病毒变异的趋势,增加的风险 status=ok
id=3 txt=天天向上 status=ok

以上程序分别含有从取document,取根节点,取节点,取CDATA节点,取属性的代码,对于一般的XML文件解析,这些API基本就够用了。

需要提一下是,CDATA节点只是用“<![CDATA[”和“]]>”将内容包起来的节点,这样做是为了让解析器不要解析其中的内容,以免发生错误,在文本较长,文本内容较多时,这样做是很必要的。但CDATA节点的解析是和普通节点是完全一样的,从上面的代码也能观察到。

另外需要提醒大家的是:有时候用dom4j解析XML会发生“Invalid byte 1 of 1-byte UTF-8 sequence.”这样的错误,但打开文本怎么看也是符合XML格式的。实际上问题在于文件存储时不是以UTF-8格式存储的,而是GBK或是其它格式。解决办法是用记事本打开XML文件,另存为,然后Ecoding选成UTF-8,保存,然后就可以正常解析了。

1.2 从字符串解析XML

相对于从文件解析XML,从字符串解析内容更为常见,解析程序除了取document的方式不一样以外,其它部分和从文件解析没什么差别,请见下面的例子:

解析程序如下:

        String xml="<words><word><id>1</id><txt status=\"OK\"><![CDATA[你好XML]]></txt></word><word><id>2</id><txt status=\"OK\"><![CDATA[你好Dom4j]]></txt></word></words>";
        Document doc= DocumentHelper.parseText(xml);

        Element rootElt = doc.getRootElement();
        Iterator<Element> iter = rootElt.elementIterator("word");

        while (iter.hasNext()) {
            Element wordElm = (Element) iter.next();

            String id = wordElm.elementTextTrim("id");
            String txt = wordElm.elementTextTrim("txt");
            String status=wordElm.element("txt").attributeValue("status");

            System.out.println("id="+id+" txt="+txt+" status="+status);
        }

控制台输入如下:

id=1 txt=你好XML status=OK
id=2 txt=你好Dom4j status=OK

2.XML之萃取

萃取是我个人定义的,实际意义指从XML中找出特定内容,刚才说过的一层层解析虽然也可以达到这个目的,但效率不高,程序可读性不好。最佳萃取方式应该是XPtah。

2.1 XPath取单节点

XML文档:

<?xml version='1.0' encoding='utf-8'?>
<rep sts="OK" a="trep" tl="cds">
    <docs>
        <d dt="ndoc1" did="d20131122020948194009045125076279783" lang="eg"
            ctime="2013-11-22T02:09:48" mtime="2013-11-22T02:09:48" orig="1"
            mime="text/x-mt-xml" wc="3">
            <p pid="1" wc="3">
                <s sid="1">
                    <t tid="1" tt="orig" wc="3">how are you</t>
                </s>
            </p>
        </d>
        <d dt="ndoc2" did="d20131122020948194009045125076279783" lang="nc"
            ctime="2013-11-22T02:09:48" mtime="2013-11-22T02:09:48" orig="0"
            mime="text/x-mt-xml" sc="100.00" wc="1">
            <p pid="1" wc="1">
                <s sid="1">
                    <t tid="1" tt="mt" src="tm" sc="100.00" wc="1">您好吗</t>
                </s>
            </p>
        </d>
    </docs>
</rep>

下面这段程序将取出以上“您好吗”这部分文字:

        SAXReader reader = new SAXReader();
        InputStream is = new FileInputStream("C:\\Users\\IBM_ADMIN\\Desktop\\2.xml");
        org.dom4j.Document doc = reader.read(is);
        Element elm = (Element) doc.selectSingleNode("//rep/docs/d[last()]/p/s/t");// 注意看Path和节点是怎么对应上的
        System.out.println( elm.getText());

下面输出正好是我们需要找的:

您好吗

可以看出XPath基本就是为萃取设计的。

2.2 XPath取多个节点

XML还是上面的XML,但取出是“ how are you ”和“ 您好吗”所在的t节点:

<?xml version='1.0' encoding='utf-8'?>
<rep sts="OK" a="trep" tl="cds">
    <docs>
        <d dt="ndoc1" did="d20131122020948194009045125076279783" lang="eg"
            ctime="2013-11-22T02:09:48" mtime="2013-11-22T02:09:48" orig="1"
            mime="text/x-mt-xml" wc="3">
            <p pid="1" wc="3">
                <s sid="1">
                    <t tid="1" tt="orig" wc="3">how are you</t>
                </s>
            </p>
        </d>
        <d dt="ndoc2" did="d20131122020948194009045125076279783" lang="nc"
            ctime="2013-11-22T02:09:48" mtime="2013-11-22T02:09:48" orig="0"
            mime="text/x-mt-xml" sc="100.00" wc="1">
            <p pid="1" wc="1">
                <s sid="1">
                    <t tid="1" tt="mt" src="tm" sc="100.00" wc="1">您好吗</t>
                </s>
            </p>
        </d>
    </docs>
</rep>

程序如下:

        SAXReader reader = new SAXReader();
        InputStream is = new FileInputStream("C:\\Users\\IBM_ADMIN\\Desktop\\2.xml");
        org.dom4j.Document doc = reader.read(is);  

        List ls=doc.selectNodes("//rep/docs/d/p/s/t");
        for(int i=0;i<ls.size();i++){
             Element elm = (Element)ls.get(i);

             System.out.println( elm.getText());
        }

输出如下:

how are you
您好吗

以上两个程序说明,无论是取单个还是多个节点,只要路径稍深,XPath就比解析方式要简单,实用。

XML,dom4j和Java的更多相关文章

  1. XML概念定义以及如何定义xml文件编写约束条件java解析xml DTD XML Schema JAXP java xml解析 dom4j 解析 xpath dom sax

    本文主要涉及:xml概念描述,xml的约束文件,dtd,xsd文件的定义使用,如何在xml中引用xsd文件,如何使用java解析xml,解析xml方式dom sax,dom4j解析xml文件 XML来 ...

  2. (转)Android 创建与解析XML—— Dom4j方式 .

    转:http://blog.csdn.net/ithomer/article/details/7521605 1.Dom4j概述 dom4j is an easy to use, open sourc ...

  3. 使用XML文件和Java代码控制UI界面

    Android推荐使用XML文件设置UI界面,然后用Java代码控制逻辑部分,这体现了MVC思想. MVC全名是Model View Controller,是模型(model)-视图(view)-控制 ...

  4. 浅谈AndroidManifest.xml与R.java及各个目录的作用

    在开发Android项目中,AndroidManifest.xml与R.java是自动生成的.但是对于测试来说,非常重要.经过师父的点拨,我对AndroidManifest.xml与R.java有了更 ...

  5. Android color(颜色) 在XML文件和java代码中

    Android color(颜色) 在XML文件和java代码中,有需要的朋友可以参考下. 1.使用Color类的常量,如: int color = Color.BLUE;//创建一个蓝色 是使用An ...

  6. Xml解析之——Java/Android/Python

    Xml解析之——Java/Android/Python 一.Xml文件 test.xml <note> <to>George</to> <from>Jo ...

  7. 第7章—SpringMVC高级技术—不用web.xml,而使用java类配置SpringMVC

    不用web.xml,而使用java类配置SpringMVC DispatcherServlet是Spring MVC的核心,按照传统方式, 需要把它配置到web.xml中. 我个人比较不喜欢XML配置 ...

  8. mybatis Mapper.xml和Mapper.java

    mybatis Mapper.xml和Mapper.java 通过Mapper.xml和Mapper.java来实现mybatis.环境和入门的一样的.关键:Mapper.xml + Mapper.j ...

  9. JAXB轻松转换xml对象和java对象

    实体类如下: package com.cn.entity; import java.util.List; import javax.xml.bind.annotation.XmlAccessType; ...

随机推荐

  1. 最大流 [USACO4.2]草地排水Drainage Ditches

    Background 在农夫约翰的农场上,每逢下雨,贝茜最喜欢的三叶草地就积聚了一潭水.这意味着草地被水淹没了,并且小草要继续生长还要花相当长一段时间.因此,农夫约翰修建了一套排水系统来使贝茜的草地免 ...

  2. 【BZOJ 2753】 2753: [SCOI2012]滑雪与时间胶囊 (分层最小树形图,MST)

    2753: [SCOI2012]滑雪与时间胶囊 Time Limit: 50 Sec  Memory Limit: 128 MBSubmit: 2457  Solved: 859 Descriptio ...

  3. VS2015常用配置

    一.调用控制台: 在VS中使用opencv或者QT过程中,完成编程后, 运行发现没有控制台窗口, 比如我们用Qt编写的界面软件, 又想看到我们在代码中添加的打印日志信息,这个时候加上控制台窗口就能实现 ...

  4. luoguP4115 QTREE4 链分治

    具体看$qzc$论文吧......陈年老物了...... 主要注意每个链头一棵线段树而不是一棵全局线段树 修改操作写完就是正确的,反而是初始化调了好一会...... 跑的还是很快的,有些地方没优化常数 ...

  5. wampserver -- 取消PHP页面Warning和Notice级别的报错

    Learn from:http://yige.org/p/91 一般遇到这样的问题,有两个方法:1.如果有服务器权限,直接把服务器上的php.ini的配置改了,改成不输出Warning和Notice级 ...

  6. web前端开发必备压缩工具整理

    影响网站打开时间有两个因素,一个是网页加载速度,另一个是网站页面的大小.网站加载速度与用户所处的网络环境及主机性能有关,而网站页面的大小则由网站开发者决定,最主要的就是web前端开发工程师的工作.本文 ...

  7. Android的Master/Detail风格界面中实现自定义ListView的单选

    原文在这里:http://duduli.iteye.com/blog/1453576 可以实现多选,那么如何实现单选呢,这里我写了一个非常简单的方法: public void onListItemCl ...

  8. TCP通信粘包问题分析和解决(全)(转)

    TCP通信粘包问题分析和解决(全) 在socket网络程序中,TCP和UDP分别是面向连接和非面向连接的.因此TCP的socket编程,收发两端(客户端和服务器端)都要有成对的socket,因此,发送 ...

  9. tomcat服务器重启后session可以继续使用

    原文:http://blog.csdn.net/e421083458/article/details/8651312 测试没有效果 配置server.xml文件,加入session保存操作 <C ...

  10. gdb对应vc调试命令

    gdb vc调试对照表: 实现功能                vc                   gdb 修改后编译              f7                   ma ...