通过DOM方式解析xml

简述:XML 指可扩展标记语言(eXtensible Markup Language)。
XML 被设计用来传输和存储数据。
XML 很重要,也很容易学习。

什么是xml?

  • XML 指可扩展标记语言(EXtensible Markup Language)。
  • XML 是一种很像HTML的标记语言。
  • XML 的设计宗旨是传输数据,而不是显示数据。
  • XML 标签没有被预定义。您需要自行定义标签。
  • XML 被设计为具有自我描述性。
  • XML 是 W3C 的推荐标准。

XML和HTML之间的差异
XML 不是 HTML 的替代。
XML 和 HTML 为不同的目的而设计:

  • XML 被设计用来传输和存储数据,其焦点是数据的内容。
  • HTML 被设计用来显示数据,其焦点是数据的外观。

HTML 旨在显示信息,而 XML 旨在传输信息。

通过XML可以自己发明标签
例:

<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>

上面实例中的标签没有在任何 XML 标准中定义过(比如 <to><from>)。这些标签是由 XML 文档的创作者发明的。
这是因为 XML 语言没有预定义的标签。
HTML 中使用的标签都是预定义的。HTML 文档只能使用在 HTML 标准中定义过的标签(如 <p><h1> 等等)。
XML 允许创作者定义自己的标签和自己的文档结构。

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文件比较大,容易影响解析性能且可能会造成内存溢出。

1.首先使用文本文档新建一个xml文件(注意编码格式)
xml代码如下:

<?xml version='1.0' encoding='UTF-8' ?>
<root>
<hang>
<产品唯一ID>aab产品唯一ID</产品唯一ID>
<通用名>aa通用名</通用名>
<商品名>aa商品名</商品名>
<剂型>aa剂型</剂型>
<批准文号>aa批准文号</批准文号>
<规格>aa规格</规格>
<包装说明>aa包装说明</包装说明>
<包装单位>aa包装单位</包装单位>
<生产企业>aa生产企业</生产企业>
<大包装转换比>aa大包装转换比</大包装转换比>
<中包装转换比>aa中包装转换比</中包装转换比>
<备注>aa备注</备注>
<库存>aa库存</库存>
<供应价>aa供应价</供应价>
<是否上架>aa是否上架</是否上架>
</hang>
<hang>
<产品唯一ID>a121</产品唯一ID>
<通用名>b12</通用名>
<商品名>c231</商品名>
<剂型>dewrwer</剂型>
<批准文号>e324324</批准文号>
<规格>f45645</规格>
<包装说明>g4543</包装说明>
<包装单位>hq324e2</包装单位>
<生产企业>i76</生产企业>
<大包装转换比>j453</大包装转换比>
<中包装转换比>k4r43r</中包装转换比>
<备注>le4tr4</备注>
<库存>mq3e2</库存>
<供应价>nefrw</供应价>
<是否上架>o56</是否上架>
</hang>
</root>

2.通过java编写DOM解析程序
java源代码:

import java.io.IOException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;


public class DOMTest {
     public static void main(String[] args) {           
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();//创建一个DocumentBuilderFactory的对象
            //创建一个DocumentBuilder的对象
            try {               
                DocumentBuilder db = dbf.newDocumentBuilder();//创建DocumentBuilder对象             
                Document document = db.parse("F://123.xml");//通过DocumentBuilder对象的parser方法加载123.xml文件到当前项目下             
                NodeList bookList = document.getElementsByTagName("hang");//获取所有book节点的集合              
                System.out.println("一共有" + bookList.getLength() + "个产品"); //通过nodelist的getLength()方法可以获取bookList的长度             
                for (int i = 0; i < bookList.getLength(); i++) {//遍历每一个book节点
                    System.out.println("=================下面开始遍历第" + (i + 1) + "个产品的内容=================");                  
                    Node book = bookList.item(i); //通过 item(i)方法 获取一个book节点,nodelist的索引值从0开始                    
                    NamedNodeMap attrs = book.getAttributes();//获取book节点的所有属性集合
                    System.out.println("第 " + (i + 1) + "个产品共有" + attrs.getLength() + "个属性");                   
                    for (int j = 0; j < attrs.getLength(); j++) {//遍历hang的属性                        
                        Node attr = attrs.item(j);//通过item(index)方法获取hang节点的某一个属性                       
                        System.out.print("属性名:" + attr.getNodeName());//获取属性名                       
                        System.out.println("--属性值" + attr.getNodeValue());//获取属性值
                    }

                    NodeList childNodes = book.getChildNodes(); //解析hang节点的子节点                  
                    System.out.println("第" + (i+1) + "个产品共有" + 
                    childNodes.getLength() + "个子节点");//遍历childNodes获取每个节点的节点名和节点值
                    for (int k = 0; k < childNodes.getLength(); k++) {                      
                        if (childNodes.item(k).getNodeType() == Node.ELEMENT_NODE) {//区分出text类型的node以及element类型的node                            
                            System.out.print("第" + (k + 1) + "个节点的节点名:" //获取了element类型节点的节点名
                            + childNodes.item(k).getNodeName());                           
                            System.out.println("--节点值是:" + childNodes.item(k).getFirstChild().getNodeValue()); //获取了element类型节点的节点值
                        }
                    }
                    System.out.println("======================结束遍历第" + (i + 1) + "个产品的内容=================");
                }
            } catch (ParserConfigurationException e) {
                e.printStackTrace();
            } catch (SAXException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }        
        }
}

运行结果如下:
这里写图片描述

一共有2个产品
=================下面开始遍历第1个产品的内容=================
 1个产品共有0个属性
第1个产品共有31个子节点
第2个节点的节点名:产品唯一ID--节点值是:aab产品唯一ID
第4个节点的节点名:通用名--节点值是:aa通用名
第6个节点的节点名:商品名--节点值是:aa商品名
第8个节点的节点名:剂型--节点值是:aa剂型
第10个节点的节点名:批准文号--节点值是:aa批准文号
第12个节点的节点名:规格--节点值是:aa规格
第14个节点的节点名:包装说明--节点值是:aa包装说明
第16个节点的节点名:包装单位--节点值是:aa包装单位
第18个节点的节点名:生产企业--节点值是:aa生产企业
第20个节点的节点名:大包装转换比--节点值是:aa大包装转换比
第22个节点的节点名:中包装转换比--节点值是:aa中包装转换比
第24个节点的节点名:备注--节点值是:aa备注
第26个节点的节点名:库存--节点值是:aa库存
第28个节点的节点名:供应价--节点值是:aa供应价
第30个节点的节点名:是否上架--节点值是:aa是否上架
======================结束遍历第1个产品的内容=================
=================下面开始遍历第2个产品的内容=================
 2个产品共有0个属性
第2个产品共有31个子节点
第2个节点的节点名:产品唯一ID--节点值是:a121
第4个节点的节点名:通用名--节点值是:b12
第6个节点的节点名:商品名--节点值是:c231
第8个节点的节点名:剂型--节点值是:dewrwer
第10个节点的节点名:批准文号--节点值是:e324324
第12个节点的节点名:规格--节点值是:f45645
第14个节点的节点名:包装说明--节点值是:g4543
第16个节点的节点名:包装单位--节点值是:hq324e2
第18个节点的节点名:生产企业--节点值是:i76
第20个节点的节点名:大包装转换比--节点值是:j453
第22个节点的节点名:中包装转换比--节点值是:k4r43r
第24个节点的节点名:备注--节点值是:le4tr4
第26个节点的节点名:库存--节点值是:mq3e2
第28个节点的节点名:供应价--节点值是:nefrw
第30个节点的节点名:是否上架--节点值是:o56
======================结束遍历第2个产品的内容=================

猜你喜欢

转载自blog.csdn.net/qq_41182503/article/details/79974659
今日推荐