当前位置: 首页 > news >正文

使用Apache Xerces解析XML文档

 
使用Apache Xerces解析XML文档
 
一、技术概述
 
在用Java解析XML时候,一般都使用现成XML解析器来完成,自己编码解析是一件很棘手的问题,对程序员要求很高,一般也没有专业厂商或者开源组织实现的好。
 
Java解析XML的原理图如下:
 
目前Java XML解析器有十多种之多,解析原理有二:使用基于事件的XML简单API(Simple API for XML)称为SAX和基于树和节点的文档对象模型(Document Object Module)称为DOM。Sun公司提供了Java API for XML Parsing(JAXP)接口来使用SAX和DOM,通过JAXP,我们可以使用任何与JAXP兼容的XML解析器。但并不是所有的Java XML解析工具都实现了SUN提供的接口。DOM4J就没有遵循SUN的JAXP规范,但非常优秀。
 
DOM 采用建立树形结构的方式访问 XML 文档,而 SAX 采用的事件模型。
 
DOM 是W3C组织推荐的处理XML的标准接口,DOM 解析器把 XML 文档转化为一个包含其内容的树,并可以对树进行遍历。用 DOM 解析模型的优点是编程容易,开发人员只需要调用建树的指令,然后利用navigation APIs访问所需的树节点来完成任务。可以很容易的添加和修改树中的元素。然而由于使用 DOM 解析器的时候需要处理整个 XML 文档,所以对性能和内存的要求比较高,尤其是遇到很大的 XML 文件的时候。由于它的遍历能力,DOM 解析器常用于 XML 文档需要频繁的改变的服务中。
 
SAX是由XML_DEV邮件列表的成员开发的,它不是某个官方机构的标准,也不由W3C组织或其他任何官方机构维护,但它是XML社区事实上的标准。虽然SAX只是“民间”标准,但是它在XML中的应用丝毫不比DOM少,几乎所有的XML解析器都支持它。SAX 解析器采用了基于事件的模型,它在解析 XML 文档的时候可以触发一系列的事件,当发现给定的tag的时候,它可以激活一个回调方法,告诉该方法制定的标签已经找到。SAX 对内存的要求通常会比较低,因为它让开发人员自己来决定所要处理的tag。特别是当开发人员只需要处理文档中所包含的部分数据时,SAX 这种扩展能力得到了更好的体现。但用 SAX 解析器的时候编码工作会比较困难,而且很难同时访问同一个文档中的多处不同数据。
 
DOM和SAX只是定义了一些接口,以及某些接口的默认实现,一个应用程序要想利用DOM或SAX访问XML文档,还需要一个实现了DOM或SAX的解析器(实现DOM和SAX中定义的接口,提供DOM和SAX定义的功能)。
 
Apache的Xerces是一个使用非常广泛的解析其,它提供了DOM和SAX的调用接口,并有多种语言的实现版本,要利用Xerces访问XML文档,只需要在应用程序中构造一个解析器实现类的对象。
 
这里面还存在一个问题,虽然使用的是标准的DOM和SAX接口,由于不同的XML解析器的实现类是不同的,如果使用另外一种解析器,仍然需要修改应用程序,只不过修改的代码量较小,需要更改XML解析器实现类的类名,然后重新编译、发布。
 
然而,对于兼容JAXP的XML解析器,我们可以选用JAXP API,这样在更换兼容JAXP解析器的时候,就不用对已发布的程序做任何的改动。
 
JAXP开发包由javax.xml包、org.w3c.dom包、org.xml.sax包及其子包组成。在javax.xml.parsers包中,定义了几个工厂类,用于加载DOM和SAX的实现类。
 
 
使用JAXP API解析XML的原理如下:
 
二、使用DOM解析XML
 
DOM的核心概念就是NODE(节点)。DOM在分析XML文档时,将组成XML文档的各个部分(元素,属性,文本,注释,处理指令等)映射成一个对象,这个对象就叫做节点。在内存中这些节点形成一棵树。整棵树就是一个节点,树中的每一个节点也是一棵树(子树)。DOM就是对这棵树的一个对象描述,我们通过访问树中的节点来存取XML文档的内容。
 
DOM定义了一个Node接口,用于表示文档树中一个节点。从这个接口派生出来更多的具体的接口。例如,表示整个文档的Document接口,表示XML文档中的一个元素的Element接口,表示元素属性的Attr接口,都是从Node接口派生而来的。在org.w3c.dom包中,表示XML文档各组成部分的接口的继承关系如图:
 
 
举个例子,引用java web开发大全,有改动:
 
students.xml
----------------------------------------------------------------------



   
        张三
        18
   
   
        李四
        20
   
----------------------------------------------------------------------
 
public class DOMStudentsInfo {
    public static void main(String[] args) {
        //获取生成 DOM 对象树的解析器
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        try {
            //从 DocumentBuilderFactory获取 DocumentBuilder实例
            DocumentBuilder db = dbf.newDocumentBuilder();
            File file = new File(/"students.xml/");
            从 XML 文档获取 DOM 文档实例
            Document doc = db.parse(file);
            //获取某节点的集合
            NodeList nl = doc.getElementsByTagName(/"student/");
            int len = nl.getLength();
            for (int i = 0; i < len; i++) {
                Element eltStu = (Element) nl.item(i);
                Node eltName = eltStu.getElementsByTagName(/"name/").item(0);
                Node eltAge = eltStu.getElementsByTagName(/"age/").item(0);
                String name = eltName.getFirstChild().getNodeValue();
                String age = eltAge.getFirstChild().getNodeValue();
                System.out.print(/"姓名:/");
                System.out.println(name);
                System.out.print(/"年龄:/");
                System.out.println(age);
                System.out.println(/"----------------------------//n/");
            }
        }
        catch (ParserConfigurationException e) {
            e.printStackTrace();
        }
        catch (SAXException e) {
            e.printStackTrace();
        }
        catch (IOException e) {
            e.printStackTrace();
        }
    }
}

 
运行结果:
 



   
        a1234
        四川省xx县xx镇xx路x段xx号
   
   
        b1234
        四川省xx市xx乡xx村xx组
   
----------------------------------------------------------------------
 
public class MyXMLReader2 extends DefaultHandler {
    java.util.Stack tags = new java.util.Stack();
    public MyXMLReader2() {
        super();
    }
    public static void main(String args[]) {
        long lasting = System.currentTimeMillis();
        try {
            SAXParserFactory sf = SAXParserFactory.newInstance();
            SAXParser sp = sf.newSAXParser();
            MyXMLReader2 reader = new MyXMLReader2();
            sp.parse(new InputSource(/"data_10k.xml/"), reader);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println(/"运行时间:/" + (System.currentTimeMillis() - lasting) + /" 毫秒/");
    }
    public void characters(char ch[], int start, int length) throws SAXException {
        String tag = (String) tags.peek();
        if (tag.equals(/"no/")) {
            System.out.print(/"车牌号码:/" + new String(ch, start, length));
        }
        if (tag.equals(/"addr/")) {
            System.out.println(/" 地址:/" + new String(ch, start, length));
        }
    }
    public void startElement(
            String uri,
            String localName,
            String qName,
            Attributes attrs) {
        tags.push(qName);
    }
}
 
运行结果:
 
            SAXReader reader = new SAXReader();
            Document doc = reader.read(f);
            Element root = doc.getRootElement();
            Element foo;
            for (Iterator i = root.elementIterator(/"value/"); i.hasNext();) {
                foo = (Element) i.next();
                System.out.print(/"车牌号码:/" + foo.elementText(/"no/"));
                System.out.println(/" 车主地址:/" + foo.elementText(/"addr/"));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println(/"运行时间:/" + (System.currentTimeMillis() - lasting) + /" 毫秒/");
    }
}
 
五、使用JDOM解析xml
 
public class MyXMLReader3 {
    public static void main(String arge[]) {
        long lasting = System.currentTimeMillis();
        try {
            SAXBuilder builder = new SAXBuilder();
            Document doc = builder.build(new File(/"data_10k.xml/"));
            Element foo = doc.getRootElement();
            List allChildren = foo.getChildren();
            for (int i = 0; i < allChildren.size(); i++) {
                System.out.print(/"车牌号码:/" + ((Element) allChildren.get(i)).getChild(/"no/").getText());
                System.out.println(/" 车主地址:/" + ((Element) allChildren.get(i)).getChild(/"addr/").getText());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println(/"运行时间:/" + (System.currentTimeMillis() - lasting) + /" 毫秒/");
    }
}
 
六、使用JAXP解析XML
 
public class MyXMLReader1 {
    public static void main(String arge[]) {
        long lasting = System.currentTimeMillis();
        try {
            File f = new File(/"data_10k.xml/");
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document doc = builder.parse(f);
            NodeList nl = doc.getElementsByTagName(/"value/");
            for (int i = 0; i < nl.getLength(); i++) {
                System.out.print(/"车牌号码:/" + doc.getElementsByTagName(/"no/").item(i).getFirstChild().getNodeValue());
                System.out.println(/" 车主地址:/" + doc.getElementsByTagName(/"addr/").item(i).getFirstChild().getNodeValue());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println(/"运行时间:/" + (System.currentTimeMillis() - lasting) + /" 毫秒/");
    }
}

相关文章:

  • 禁ping以及清理系统多余账号说明
  • 使用dom4j和XPath解析XML之例子二
  • [改善Java代码]子列表只是原列表的一个视图
  • 使用Java自带SAX工具解析XML
  • 使用SAX解析XML (控制台程序)
  • PMI列子1
  • 一个简单实用的AJAX例子
  • VS使用技巧
  • 一个最简单的AJAX实例及解析
  • 静态库中有图片,改如何存放呢??
  • 用Java结合SAX 2.0 解析XML文档
  • HDU 2594 Simpsons’ Hidden Talents(辛普森一家的潜在天赋)
  • 在Dom4j中使用xpath
  • C# 文件与目录的基本操作(System.IO)
  • 在JavaScript中使用Java
  • .pyc 想到的一些问题
  • 【翻译】Mashape是如何管理15000个API和微服务的(三)
  • OSS Web直传 (文件图片)
  • pdf文件如何在线转换为jpg图片
  • Redis 懒删除(lazy free)简史
  • Selenium实战教程系列(二)---元素定位
  • XML已死 ?
  • ionic异常记录
  • $refs 、$nextTic、动态组件、name的使用
  • (145)光线追踪距离场柔和阴影
  • (Python第六天)文件处理
  • (差分)胡桃爱原石
  • (二)windows配置JDK环境
  • (附源码)ssm基于web技术的医务志愿者管理系统 毕业设计 100910
  • (一)Linux+Windows下安装ffmpeg
  • (转)chrome浏览器收藏夹(书签)的导出与导入
  • (转)Google的Objective-C编码规范
  • (轉貼) UML中文FAQ (OO) (UML)
  • . NET自动找可写目录
  • .cn根服务器被攻击之后
  • .NET 编写一个可以异步等待循环中任何一个部分的 Awaiter
  • .NET/C# 使窗口永不激活(No Activate 永不获得焦点)
  • .NET:自动将请求参数绑定到ASPX、ASHX和MVC(菜鸟必看)
  • .NET版Word处理控件Aspose.words功能演示:在ASP.NET MVC中创建MS Word编辑器
  • .net程序集学习心得
  • /3GB和/USERVA开关
  • @JSONField或@JsonProperty注解使用
  • [ai笔记3] ai春晚观后感-谈谈ai与艺术
  • [AutoSar]BSW_OS 01 priority ceiling protocol(PCP)
  • [BUUCTF 2018]Online Tool
  • [c]统计数字
  • [CISCN 2019华东南]Web11
  • [corCTF 2022] CoRJail: From Null Byte Overflow To Docker Escape
  • [EFI]Dell Latitude-7400电脑 Hackintosh 黑苹果efi引导文件
  • [EULAR文摘] 利用蛋白组学技术开发一项蛋白评分用于预测TNFi疗效
  • [flume$2]记录一个写自定义Flume拦截器遇到的错误
  • [JS]数据类型
  • [Linux]如何理解kernel、shell、bash
  • [Linux内存管理-分页机制]—把一个虚拟地址转换为物理地址
  • [PHP]关联和操作MySQL数据库然后将数据库部署到ECS