• XML,dom4j和Java


    写这篇文章的目的是把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就比解析方式要简单,实用。

  • 相关阅读:
    每一个合格的家庭主妇都是生产厂长的有力竞争者
    单点登录在ASP.NET上的简单实现
    Asp.net(C#)给图片加上水印效果
    Asp.net Ajax框架教程
    记入cookie一个ip一天只弹一次的弹窗代码JavaScript实例教程
    【转】ASP.net2。0中解决无法获取 GridView 隐藏列值问题
    javascript 动态添加表格行
    IndexOf方法,LastIndexOf方法,substring方法
    SQL 批量插入数据
    js 前台找控件(table里找控件)
  • 原文地址:https://www.cnblogs.com/heyang78/p/3441710.html
Copyright © 2020-2023  润新知