解析xml文档

来源:互联网 发布:一起走软件刷步数 编辑:程序博客网 时间:2024/05/01 18:10

XML的解析

若要处理XML文档,提取或修改其中的数据信息,就必须先对XML文档进行解析,从而识别出XML文档的结构和其中的数据。因此,就需要一些程序来对XML文件进行解析,并称这些程序为XML解析器。XML文档最基本的解析器有两种,分别是文档对象模型(Document Object Model简称DOM)和XML解析的简单API(SAX),这两者本质上都是一种Java的接口。

 

DOM处理

文档对象模型(Document Object Model简称DOM),是一种基于对象的API,使用DOM对XML文档进行解析时,会在内存中生成与XML文档内容对应的对象模型。当解析完成时,内存中会生成与XML文档结构对应的DOM对象树。这样便能够根据树的结构,以节点形式来对文档进行操作。

Java的JDK中包含了DOM分析器,在javax.xml.parsers包中,提供了DocumentBuilder类和DocumentBuilderFactory类。若要解析XML文档,可以采用如下步骤。

(1)需要一个DocumentBuilder类的对象(该对象可以使用DocumentBuilderFactory类的静态方法newInstance()来获取)。

(2)使用该对象中的parse()方法来解析XML文档。该过程就如同文件流的高级用法,首先需要建立File对象,用来将XML文档加载到内存中,之后使用DocumentBuilder对象中的parse()方法来解析这个XML文档。

(3)parse()方法将返回一个Document对象(Document类在org.w3c.dom包中),该对象正是XML文档所对应的树状结构,并保存在内存中。

使用Java程序解析XML文档“Demo.xml”的代码片断如下所示。

 

import java.io.*;

import javax.xml.parsers.DocumentBuilderFactory;

import javax.xml.parsers.DocumentBuilder;

import org.w3c.dom.*;       //导入使用DOM解析XML文件的包

class ParseXML

{

      ……

      public static void main(String args[])

      {

            //创建File的对象file,用来在内存中加载XML文件

            File file = new File(“Demo.xml”);      

            //使用DocumentBuilderFactory类的静态方法newInstance(),来获取该类的一个对象factory

            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

            //使用factory对象的newDocumentBuilder()方法,来获取DocumentBuilder类的对象

            DocumentBuilder builder = factory.newDocumentBuilder();

            //使用DocumentBuilder类对象的parse()方法来解析XML文件,并返回Document对象

            Document doc = builder.parse(file);

            ……

}

}

通过上述代码,可以为所要解析的XML文件,创建一个Document对象doc,之后可以通过doc对象中的大量方法对XML文件实现各类操作,例如添加、删除、修改元素等。

代码22-5中,使用DOM解析器,实现对代码中的XML文档进行解析,提取出两个“name”节点元素的内容。

代码22-5  使用DOM解析器实现对XML文档的解析XMLParse.java

import java.io.*;

import javax.xml.parsers.DocumentBuilderFactory;

import javax.xml.parsers.DocumentBuilder;

import org.w3c.dom.*;

import org.w3c.dom.CharacterData;

public class XMLParse

{

      public static void main(String[] args)

      {

            //创建File的对象file,用来在内存中加载XML文件

            File file = new File("C://Demo.xml");

            //使用DocumentBuilderFactory类的静态方法newInstance(),来获取该类的一个对象factory

            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

            try

            {

                  //使用factory对象的newDocumentBuilder()方法,来获取DocumentBuilder类的对象

                  DocumentBuilder builder = factory.newDocumentBuilder();

                 

                  //使用DocumentBuilder类对象的parse()方法,来解析XML文件,并返回Document对象

                  Document doc = builder.parse(file);

                 

                  //使用doc对象的getDocumentElement()来获取根元素

                  Element element1 = doc.getDocumentElement();

                  //使用element对象的getNodeName()方法获取根元素的名字并显示出来

                  String str = element1.getNodeName();

                  System.out.println(str);

                 

                  //使用根元素对象element1中的方法getElementsByTagName(),

                  //来获得其子元素名为"name"的一个列表list

                  NodeList list = element1.getElementsByTagName("name");

                  //使用getLength()方法获得该列表的长度

                  int n = list.getLength();

                 

                  //通过循环,分别得到并显示元素名为"name"的元素内容

                  for (int i = 0; i < n; i++)

                  {

                        //获得列表中的每一个名为"name"的元素

                        Node node = list.item(i);

                        //获得该元素对应的内容

                        String value = node.getNodeValue();

                        System.out.println(value);

                  }

            }catch(Exception e){}

      }

}

 

 SAX处理

使用SAX同样可以完成对XML文档的解析,其对XML文件解析时,会生成相应的事件。与DOM不同的是,当使用DOM解析XML文档的时候,DOM程序会将整个XML文档都读入到一个树状结构中,并存储于内存。若遇到XML文档较大,并且只需要解析XML文档中一部分数据的时候,使用DOM解析器解析的速度就会明显变慢,效率很低。在这种情况下,可以选择使用SAX解析器。使用SAX解析器对XML文档进行解析时,程序会从XML文档开始位置起进行解析,同时根据已经定义好的事件处理器,来决定当前所解析的部分(元素、属性或时元素内容)是否有必要记录并存储。

在使用SAX解析器之前,首先要获得SAX解析器。在javax.xml.parsers包中,分别提供了 SAXParser类和SAXParserFactory类,可以通过创建SAXParserFactory类的对象factory,并使用该对象的 newSAXParser()方法来获取SAX解析器(saxParser),如下所示。

SAXParserFactory factory = SAXParserFactory.newInstance();

SAXParser saxParser = factory.newSAXParser();

在获取了SAX解析器saxParser对象之后,就可以使用该对象的parse()方法来对XML文档进行解析,语法格式如下。

saxParser。Parse(source , handler);

其中,source参数可以是File类对象所指定的文件名及所在目录,也可以是URL字符串,同样也可以为一个输入流;handler参数则是DefaultHandler类的对象,其中的方法可以用于定义事件处理器。例如:

public void startElement(String namespace,String lname,String qname,Attributes att);

该方法就是DefaultHandler类的对象handler中,用于处理XML文档的一种方法,它包含4个参数,namespace参数用于描述元素的名字空间;lname参数用于描述元素本地名;qname参数用于描述元素名;att参数则是用来描述属性的。

SAX解析器的使用方法如下。

(1)事先规定事件处理的方法(包括遇到什么样元素该怎样处理等)。

(2)SAX解析器开始解析XML文档,当遇到每一个元素时,便会去查看之前定义的事件处理中(也就是 DefaultHandler类的对象handler中),该元素是否符合被处理的条件,若符合则执行该方法,对元素进行相应处理;否则就跳过该元素,继续分析下面的每一个元素。

代码22-6中,使用SAX解析器,实现对代码22-4中的XML文档(Demo3.xml)进行解析,提取出包含属性的节点元素名称和内容。

代码22-6  使用SAX解析器实现对XML文档的解析SAXParseXML.java

 

import org.xml.sax.Attributes;

 

import org.xml.sax.SAXException;

 

import org.xml.sax.Locator;

 

import org.xml.sax.InputSource;

 

import org.xml.sax.helpers.DefaultHandler;

 

import javax.xml.parsers.SAXParser;

 

import javax.xml.parsers.SAXParserFactory;

 

public class SAXParseXML

 

{

      public static void main(String[] args)

 

      {

            try

 

            {

 

                  //用于创建SAXParserFactory类对象factory

 

                  SAXParserFactory factory = SAXParserFactory.newInstance();

 

                 

                  //利用SAXParserFactory类对象factory的newSAXParser()方法,来获取SAX解析器

 

                  SAXParser saxParser = factory.newSAXParser();

 

                 

                  //创建自定义事件处理类的对象

 

                  MyHandler myHandler = new MyHandler();

                 

                  //使用SAX解析器对象中的parse()方法解析XML文档

 

                  saxParser.parse(new InputSource("c://Demo3.xml"),myHandler);

 

            }

 

            catch(SAXException e1){}

 

            catch(Exception e2){}     

      }

}

 

class MyHandler extends DefaultHandler

 

{     //自定义事件处理类

 

      public void startElement(String namespace,String lname,String qname,Attributes att)

 

      {     //元素开始事件处理

 

            if(att!=null)   //当元素的属性不为空值时触发事件处理

 

            {

                   for (int i = 0; i < att.getLength(); i++)

 

                   {

 

                          //用于获取该元素的名称

 

                          System.out.println("元素名为:"+qname);

 

                          if(att.getQName(i).equals("edition"))

 

                          {

 

                                //用于获取"edition"属性的名称和属性值

 

                                System.out.print("属性名为:"+att.getQName(i));

 

                                System.out.println(",属性值为:"+att.getValue(i));

                          }

 

                          if(att.getQName(i).equals("isbn"))

 

                          {

                                //用于获取"isbn"属性的名称和属性值

 

                                System.out.print("属性名为:"+att.getQName(i));

 

                                System.out.println(",属性值为:"+att.getValue(i));

                          }

                   }

            }

      }

}

 

原创粉丝点击