解析】举例JAVA中如何解析xml,不同方式有和优缺点?_第2页回答

2021-11-15 10:17发布

14条回答
我的网名不再改
2楼 · 2021-11-17 11:34

1. DOM(Document Object Model)

DOM是用与平台和语言无关的方式表示XML 文档的官方 W3C标准。DOM

是以层次结构组织的节点或信息片断的集合。这个层次结构允许开发人员在

树中寻找特定信息。分析该结构通常需要加载整个文档和构造层次结构,然

后才能做任何工作。由于它是基于信息层次的,因而 DOM 被认为是基于树

或基于对象的。

【优点】

①允许应用程序对数据和结构做出更改。

②访问是双向的,可以在任何时候在树中上下导航,获取和操作任意部分的

数据。

【缺点】

①通常需要加载整个 XML 文档来构造层次


一般来说,SAX 还比它的替代者 DOM 快许多。

选择 DOM 还是选择 SAX? 对于需要自己编写代码来处理 XML 文档的开

发人员来说, 选择 DOM 还是 SAX 解析模型是一个非常重要的设计决策。

DOM 采用建立树形结构的方式访问 XML 文档,而 SAX 采用的是事件模型。

DOM 解析器把 XML 文档转化为一个包含其内容的树,并可以对树进行遍

历。用 DOM 解析模型的优点是编程容易,开发人员只需要调用建树的指令,

然后利用 navigation APIs 访问所需的树节点来完成任务。可以很容易的添

加和修改树中的元素。然而由于使用 DOM 解析器的时候需要处理整个 XML

文档,所以对性能和内存的要求比较高,尤其是遇到很大的 XML 文件的时

候。由于它的遍历能力,DOM 解析器常用于 XML 文档需要频繁的改变的

服务中。

SAX 解析器采用了基于事件的模型,它在解析 XML 文档的时候可以触发一

系列的事件,当发现给定的 tag 的时候,它可以激活一个回调方法,告诉该

方法制定的标签已经找到。SAX 对内存的要求通常会比较低,因为它让开发

人员自己来决定所要处理的 tag.特别是当开发人员只需要处理文档中所包

含的部分数据时,SAX 这种扩展能力得到了更好的体现。但用 SAX 解析器

的时候编码工作会比较困难,而且很难同时访问同一个文档中的多处不同数

据。

【优势】

①不需要等待所有数据都被处理,分析就能立即开始。

②只在读取数据时检查数据,不需要保存在内存中。


③可以在某个条件得到满足时停止解析,不必解析整个文档。

④效率和性能较高,能解析大于系统内存的文档。

【缺点】

①需要应用程序自己负责 TAG 的处理逻辑(例如维护父/子关系等),文档

越复杂程序就越复杂。

②单向导航,无法定位文档层次,很难同时访问同一文档的不同部分数据,

不支持 XPath。

3. JDOM(Java-based Document Object Model)

JDOM 的目的是成为 Java 特定文档模型,它简化与 XML 的交互并且比使用

DOM 实现更快。由于是第一个 Java 特定模型,JDOM 一直得到大力推广

和促进。正在考虑通过“Java 规范请求 JSR-102”将它最终用作“Java 标

准扩展”。从 2000 年初就已经开始了 JDOM 开发。

JDOM 与 DOM 主要有两方面不同。首先,JDOM 仅使用具体类而不使用

接口。这在某些方面简化了 API,但是也限制了灵活性。第二,API 大量使

用了 Collections 类,简化了那些已经熟悉这些类的 Java 开发者的使用。

JDOM 文档声明其目的是“使用 20%(或更少)的精力解决 80%(或更多)

Java/XML 问题”(根据学习曲线假定为 20%)。JDOM 对于大多数 Java/XML

应用程序来说当然是有用的,并且大多数开发者发现 API 比 DOM 容易理解

得多。JDOM 还包括对程序行为的相当广泛检查以防止用户做任何在 XML

中无意义的事。然而,它仍需要您充分理解 XML 以便做一些超出基本的工

作(或者甚至理解某些情况下的错误)。这也许是比学习 DOM 或 JDOM 接


口都更有意义的工作。

JDOM 自身不包含解析器。它通常使用 SAX2 解析器来解析和验证输入 XML

文档(尽管它还可以将以前构造的 DOM 表示作为输入)。它包含一些转换

器以将 JDOM 表示输出成 SAX2 事件流、DOM 模型或 XML 文本文档。

JDOM 是在 Apache 许可证变体下发布的开放源码。

【优点】

①使用具体类而不是接口,简化了 DOM 的 API。

②大量使用了 Java 集合类,方便了 Java 开发人员。

【缺点】

①没有较好的灵活性。

②性能较差。

4. DOM4J(Document Object Model for Java)

虽然 DOM4J 代表了完全独立的开发结果,但最初,它是 JDOM 的一种智

能分支。它合并了许多超出基本 XML 文档表示的功能,包


在添加灵活性、XPath 集成和对大文档处理的目标时,DOM4J 的目标与

JDOM 是一样的:针对 Java 开发者的易用性和直观操作。它还致力于成为

比 JDOM 更完整的解决方案,实现在本质上处理所有 Java/XML 问题的目

标。在完成该目标时,它比 JDOM 更少强调防止不正确的应用程序行为。

DOM4J 是一个非常非常优秀的 Java XML API,具有性能优异、功能强大

和极端易用使用的特点,同时它也是一个开放源代码的软件。如今你可以看

到越来越多的 Java 软件都在使用 DOM4J 来读写 XML,特别值得一提的是

连 Sun 的 JAXM 也在用 DOM4J. 【优点】

①大量使用了 Java 集合类,方便 Java 开发人员,同时提供一些提高性能的

替代方法。

②支持 XPath。

③有很好的性能。

【缺点】

①大量使用了接口,API 较为复杂。

二、比较

1. DOM4J 性能最好,连 Sun 的 JAXM 也在用 DOM4J。目前许多开源项目

中大量采用 DOM4J,例如大名鼎鼎的 Hibernate 也用 DOM4J 来读取 XML

配置文件。如果不考虑可移植性,那就采用 DOM4J. 2. JDOM 和 DOM 在性能测试时表现不佳,在测试 10M 文档时内存溢出,

但可移植。在小文档情况下还值得考虑使用 DOM 和 JDOM.虽然 JDOM 的


开发者已经说明他们期望在正式发行版前专注性能问题,但是从性能观点来

看,它确实没有值得推荐之处。另外,DOM 仍是一个非常好的选择。DOM

实现广泛应用于多种编程语言。它还是许多其它与 XML 相关的标准的基础,

因为它正式获得 W3C 推荐(与基于非标准的 Java 模型相对),所以在某些

类型的项目中可能也需要它(如在 JavaScript 中使用 DOM)。

3. SAX 表现较好,这要依赖于它特定的解析方式-事件驱动。一个 SAX 检

测即将到来的 XML 流,但并没有载入到内存(当然当 XML 流被读入时,会

有部分文档暂时隐藏在内存中)。

我的看法:如果 XML 文档较大且不考虑移植性问题建议采用 DOM4J;如

果 XML 文档较小则建议采用 JDOM;如果需要及时处理而不需要保存数据

则考虑 SAX。但无论如何,还是那句话:适合自己的才是最好的,如果时间

允许,建议大家讲这四种方法都尝试一遍然后选择一种适合自己的即可。


20200921文 - 做更棒的自己!
3楼 · 2021-11-19 12:18

(I)Java通过DOM解析XML

1>得到DOM解析器的工厂实例
  DocumentBuilderFactory domfac=DocumentBuilderFactory.newInstance();
  得到javax.xml.parsers.DocumentBuilderFactory;类的实例就是我们要的解析器工厂
  
2>从DOM工厂获得DOM解析器
  DocumentBuilder dombuilder=domfac.newDocumentBuilder();
  通过javax.xml.parsers.DocumentBuilderFactory实例的静态方法newDocumentBuilder()得到DOM解析器
  
3>把要解析的XML文档转化为输入流,以便DOM解析器解析它
  InputStream is=new FileInputStream("bin/library.xml");
  InputStream是一个接口。
4>解析XML文档的输入流,得到一个Document
  Document doc=dombuilder.parse(is);
  由XML文档的输入流得到一个org.w3c.dom.Document对象,以后的处理都是对Document对象进行的
  
5>得到XML文档的根节点
  Element root=doc.getDocumentElement();
  在DOM中只有根节点是一个org.w3c.dom.Element对象。
  
6>得到节点的子节点
  NodeList books=root.getChildNodes();
  for(int i=0;i
Node book=books.item(i);
  }
   这是用一个org.w3c.dom.NodeList接口来存放它所有子节点的,还有一种轮循子节点的方法,后面有介绍
  
7>取得节点的属性值
  String email=book.getAttributes().getNamedItem("email").getNodeValue();
  System.out.println(email);
  注意,节点的属性也是它的子节点。它的节点类型也是Node.ELEMENT_NODE
  
8>轮循子节点
  for(Node node=book.getFirstChild();node!=null;node=node.getNextSibling()){
  
    if(node.getNodeType()==Node.ELEMENT_NODE){
  
     if(node.getNodeName().equals("name")){
  
    String name=node.getNodeValue();
  
    String name1=node.getFirstChild().getNodeValue();
  
   ...
  
    if(node.getNodeName().equals("price")){
  
    String price=node.getFirstChild().getNodeValue();
...

Java通过SAX解析XML
Simple API for XML(简称SAX)是个循序存取XML的解析器API。
一个实现SAX的解析器(也就是“SAX Parser”)以一个串流解析器的型式作用,拥有事件驱动API。由使用者定义回调函数,解析时,若发生事件的话会被调用。SAX事件包括:
XML 文字 节点
XML 元素 节点
XML 处理指令
XML 注释

Java代码


谢成志
6626310xie

1988/11/28

ermao
images/head1.jpg




此为下面即将解析度简单xml结构,并将其封装成一个User对象。

////////////////////////////////////////////////////////////////////////////////////

Java代码
package com.xcz.xml;

import java.io.File;
import java.io.IOException;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.SAXException;

import com.xcz.util.SaxUtil;

public class Sax4XML {

public static void main(String[] args) {

try {
//1.获取factory
SAXParserFactory factory = SAXParserFactory.newInstance();
//2.获取parser
SAXParser parser = factory.newSAXParser();
//3.获取解析时的监听器对象
SaxUtil su = new SaxUtil();
//4.开始解析
parser.parse(new File("src/user-params.xml"), su);

System.out.println(su.getUser());

} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

}
}


////////////////////////////////////////////////////////////////////////////////////

Java代码
package com.xcz.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import com.xcz.po.HeadPic;
import com.xcz.po.User;

/**
* 定义xml解析时的监听类
*
* 实现方式有很多,可以实现接口:ContentHandler,DTDHandler, EntityResolver 和 ErrorHandler
* 但我们常用的继承:DefaultHandler
*/
public class SaxUtil extends DefaultHandler {

private User user;
private HeadPic headPic;
private String content;
private SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");

@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
content = new String(ch, start, length);
}

//当解析到文本开始时触发
@Override
public void startDocument() throws SAXException {
super.startDocument();
}

//当解析到文本结束时触发
@Override
public void endDocument() throws SAXException {
super.endDocument();
}

//当解析到元素开始时触发
@Override
public void startElement(String uri, String localName, String name,
Attributes attributes) throws SAXException
{
if("user".equals(name))
{
user = new User();
}
if("headpic".equals(name))
{
headPic = new HeadPic();
}
}

//当解析到元素结束时触发
@Override
public void endElement(String uri, String localName, String name)
throws SAXException
{
if("username".equals(name))
{
user.setUsername(content);
}
if("password".equals(name))
{
user.setPassword(content);
}
if("sex".equals(name))
{
user.setSex(content);
}
if("birthday".equals(name))
{
try {
user.setBirthday(sdf.parse(content));
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if("pictitle".equals(name))
{
headPic.setPicTitle(content);
}
if("picurl".equals(name))
{
headPic.setPicUrl(content);
user.setHeadPic(headPic);
}

}

public User getUser(){
return user;
}

}


[优点]

(1).节约内存开销

SAX解析器在某些方面优于DOM风格解析器,因为SAX解析器的内存使用量一般远低于DOM解析器使用量。DOM解析器在任何处理开始之前,必须将xml以整棵树放在内存,所以DOM解析器的内存使用量完全根据输入资料的大小。相对来说,SAX解析器的内存内容,是只基于XML档案的最大深度(XML树的最大深度)和单一XML项目上XML属性储存的最大资料。

(2)解析速度快

因为SAX事件驱动的本质,处理文件通常会比DOM风格的解析器快。

[缺点]

SAX事件驱动的模型对于XML解析很有用,但它确实有某些缺点。

某些种类的XML验证需要存取整份文件。例如,一个DTD IDREF属性需要文件内有项目使用指定字串当成DTD ID属性。要在SAX解析器内验证,必须追踪每个之前遇过的ID和IDREF属性,检查是否有任何相符。更甚者,一个IDREF找不到对应的ID,使用者只会在整份文件都解析完后才发现,若这种连结对于建立有效输出是重要的,那用在处理整份文件的时间只是浪费

aijingda
4楼 · 2021-11-19 17:53

使用DOM(JAXP Crimson解析器)

DOM是用与平台和语言无关的方式表示XML文档的官方W3C标准。DOM是以层次结构组织的节点或信息片断的集合。这个层次结构允许开发人员在树中寻找特定信息。分析该结构通常需要加载整个文档和构造层次结构,然后才能做任何工作。由于它是基于信息层次的,因而DOM被认为是基于树或基于对象的。DOM以及广义的基于树的处理具有几个优点。首先,由于树在内存中是持久的,因此可以修改它以便应用程序能对数据和结构作出更改。它还可以在任何时候在树中上下导航,而不是像SAX那样是一次性的处理。DOM使用起来也要简单得多。

实现方法:

import java.io.*;
import java.util.*;
import org.w3c.dom.*;
import javax.xml.parsers.*;
public class MyXMLReader{
 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();
}


那些年很冒险的梦。
5楼 · 2021-11-23 16:30

1.DOM生成和解析XML文档

为 XML 文档的已解析版本定义了一组接口。解析器读入整个文档,然后构建一个驻留内存的树结构,然后代码就可以使用 DOM
接口来操作这个树结构。优点:整个文档树在内存中,便于操作;支持删除、修改、重新排列等多种功能;缺点:将整个文档调入内存(包括无用的节点),浪费时间和空间;使用场合:一旦解析了文档还需多次访问这些数据;硬件资源充足(内存、CPU)。

2.SAX生成和解析XML文档

为解决DOM的问题,出现了SAX。SAX
,事件驱动。当解析器发现元素开始、元素结束、文本、文档的开始或结束等时,发送事件,程序员编写响应这些事件的代码,保存数据。优点:不用事先调入整个文档,占用资源少;SAX解析器代码比DOM解析器代码小,适于Applet,下载。缺点:不是持久的;事件过后,若没保存数据,那么数据就丢了;无状态性;从事件中只能得到文本,但不知该文本属于哪个元素;使用场合:Applet;只需XML文档的少量内容,很少回头访问;机器内存少;

3.DOM4J生成和解析XML文档

DOM4J 是一个非常非常优秀的Java XML
API,具有性能优异、功能强大和极端易用使用的特点,同时它也是一个开放源代码的软件。如今你可以看到越来越多的 Java 软件都在使用 DOM4J 来读写
XML,特别值得一提的是连 Sun 的 JAXM 也在用 DOM4J。

4.JDOM生成和解析XML
为减少DOM、SAX的编码量,出现了JDOM;优点:20-80原则,极大减少了代码量。使用场合:要实现的功能简单,如解析、创建等,但在底层,JDOM还是使用SAX(最常用)、DOM、Xanan文档。

visonx
6楼 · 2021-12-17 10:23

SAX处理的优点非常类似于流媒体的优点。分析能够立即开始,而不是等待所有的数据被处理。而且,由于应用程序只是在读取数据时检查数据,因此不需要将数据存储在内存中。这对于大型文档来说是个巨大的优点。事实上,应用程序甚至不必解析整个文档;它可以在某个条件得到满足时停止解析。一般来说,SAX还比它的替代者DOM快许多。

722
7楼 · 2022-03-15 11:08

常见JAVA解析XML的四种方式优缺点对比
一、DOM(Document Object Model)解析
优点:
1)允许应用程序对数据和结构做出更改。
2)访问是双向的,可以在任何时候再树中上、下导航获取、操作任意部分的数据。
缺点:
解析XML文档的需要加载整个文档来构造层次结构,消耗内存资源大。
应用范围:
遍历能力强,常应用于XML文档需要频繁改变的服务中。

Java使用步骤:
创建一个DocumentBuilderFactory对象。
创建一个DocumentBuilder对象。
通过DocumentBuilder的parse方法加载XML到当前工程目录下。
通过getElementsByTagName方法获取所有XML所有节点的集合。
遍历所有节点。
通过item方法获取某个节点的属性。
通过getNodeName和getNodeValue方法获取属性名和属性值。
通过getChildNodes方法获取子节点,并遍历所有子节点。
通过getNodeName和getTextContent方法获取子节点名称和子节点值。

二. SAX(Simple API for XML)解析
优点:
1)不需要等待所有的数据被处理,解析就可以开始。
2)只在读取数据时检查数据,不需要保存在内存中。
3) 可以在某一个条件满足时停止解析,不必要解析整个文档。
4) 效率和性能较高,能解析大于系统内存的文档。
缺点:
1)解析逻辑复杂,需要应用层自己负责逻辑处理,文档越复杂程序越复杂。
2)单向导航,无法定位文档层次,很难同时同时访问同一文档的不同部分数据,不支持XPath.

解析步骤:
获取一个SAXParserFactory的实例。
通过factory获取SAXParser实例。
创建一个handler对象。
通过parser的parse()方法来解析XML。

三、JDOM解析(需要引入jdom.jar包)
特征:
1、仅使用具体类,而不使用接口。
2、API大量使用了Collections类。
步骤:
1.创建一个SAXBuilder的对象
2.创建一个输入流,将xml文件加载到输入流中
3.通过saxBuilder的build方法,将输入流加载到saxBuilder中
4.通过document对象获取xml文件的根节点
5.获取根节点下的子节点的List集合。

四、 DOM4J(Document Object Model for Java)解析(需要引入dom4j-1.6.1.jar)
优点:

性能很好
大量使用Java集合类,开发简便,同时也提供了一些提高性能的代替方法。
支持XPath。
缺点:
API比较复杂。
步骤:
1.创建SAXReader的对象reader
2.通过reader对象的read()方法加载books.xml文件,获取document对象
3.通过document对象获取根节点bookstore
4.通过element对象的elementIterator获取迭代器
5.遍历迭代器,获取根节点中的信息
6.获取book的属性名和属性值
7.通过book对象的elementIterator获取节点元素迭代器
8.遍历迭代器,获取子节点中的信息
9.获取节点名和节点值


相关问题推荐

    没有解决我的问题,去提问