使用Java操作XML的开源框架比较多,如著名的Dom4J、JDOM等,但个人认为不管你用那个框架都要对JDK原生的API有所了解才能更得心应手的应用。本篇就来简单了解下原生的XML API。

JAVA的XML API

XML的开放性和Java的开源性注定它们是一种完美结合,因此Sun提供了一套专门用于处理XML的Java API:JAXP,JAXP遵循XML的两种解析标准:DOM(Document Object Model)和SAX(Simple API for XML Parsing),JAXP也支持XSLT(XML Stylesheet Language Transformation)标准,可控制数据的表现形式和XML文档与HTML等其他文档之间的数据转换。

  • DOM是对对文档结构及其内容的树形描述,该模型中的每个节点对应XML文档中的各种组成部分。使用DOM树,应用程序可以反复访问其中的某个节点、可以增加、删除、修改节点。DOM树中的节点分为两大类型:元素节点和文本节点。以DOM方式解析XML有以下优点:

    1. DOM将文本文件转化为抽象的树节点表示,能够避免文档在语法方面的错误,从而保证正确的语法和格式的正规性;
    2. DOM创建的节点树是对XML文档内容及其逻辑关系的正确反映,因而它是从XML语法规范中抽取内容而又高于语法约束的;同时,也使得对DOM树进行修改比修改XML文档本身要简单得多;
    3. DOM树不仅能够如实反映XML文档本身的层次结构,还可以很好地反映关系数据库中具有雪花结构的层次信息;
  • SAX不同于DOM,严格来说它并不是一种规范或标准。SAX解析是一种以时间驱动的流式解析,解析过程中按文档中的元素出现顺序逐个访问和处理元素。由于对XML文档组成部分的访问是一次性的,使用SAX时,解析器想应用程序报告解析事件流,来告知应用程序文档的内容。SAX解析方式具有以下特点:

    1. 对所解析的XML文件没有大小限制:由于SAX无须将整个XML文档载入内存,且处理时对内存占用并不随处理XML文档的大小而变化,因而对被处理文件的大小没要求;
    2. 简单易用;
    3. 处理速度快:由于以时间驱动的方式进行文档处理,无须对某个对象进行反复处理,因而速度很快;
    4. 不能对文档的组成部分进行随机存取:因为文档并没有载入内存,其处理是流式的,因而也难以实现对文档做复杂的查询;

    总体来说SAX解析占用的内存少,速度快,适用于对文档进行一次性处理情况。

JAXP的主要API都定义在javax.xml.parsers中,该包为开发SAX解析器和DOM解析器提供了公共接口:

  • 包org.w3c.dom负责以DOM方式解析;
  • 包org.xml.sax负责定义SAX API;
  • 包javax.xml.transform定义了将XML转换为其他形式的XSLT API;

解析示例

oseye.xml

<?xml version="1.0"?>
<note>
<to>oseye.net</to>
<from>kevin</from>
<heading>Reminder</heading>
<body>Don't forget the meeting!</body>
</note>

Dom方式解析

package com.byd.DomXML;

import java.io.File;
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.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException; /**
* Dom方式解析XML
*/
public class App {
public static void main(String[] args) throws ParserConfigurationException,
SAXException, IOException {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder bulder = factory.newDocumentBuilder();
Document doc = bulder.parse(new File("d:/mytemp/xml/oseye.xml"));
// 获取根元素
Element element = doc.getDocumentElement();
NodeList list = element.getChildNodes();
for (int iloop = 0; iloop < list.getLength(); iloop++) {
Node node = list.item(iloop);
if (node.getNodeType() == Node.ELEMENT_NODE) {
System.out.println(node.getNodeName() + ":"
+ node.getTextContent());
}
}
}
}

SAX方式解析

package com.byd;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set; import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory; import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler; /**
* SAX方式解析
*/
public class App
{
public static void main( String[] args ) throws Exception
{
SAXParserFactory factory=SAXParserFactory.newInstance();
SAXParser sparse=factory.newSAXParser();
SaxHandler handler=new SaxHandler("note");
sparse.parse(new File("d:/mytemp/xml/oseye.xml"),handler);
//输出
for(Map<String,String> map:handler.getList()){
Iterator<String> iterator=map.keySet().iterator();
while(iterator.hasNext()){
String key=iterator.next();
System.out.println(key+":"+map.get(key));
}
}
}
} class SaxHandler extends DefaultHandler {
private HashMap<String, String> map = null;
private List<HashMap<String, String>> list = null;
//正在解析的元素的标签
private String currentTag = null;
//正在解析的元素的值
private String currentValue = null;
private String nodeName = null; public List<HashMap<String, String>> getList(){
return list;
} public SaxHandler(String nodeName) {
this.nodeName = nodeName;
} @Override
public void startDocument() throws SAXException {
//当读到一个开始标签的时候,会触发这个方法
list = new ArrayList<HashMap<String,String>>();
} @Override
public void startElement(String uri, String localName, String name,
Attributes attributes) throws SAXException {
//当遇到文档的开头的时候,调用这个方法
if(name.equals(nodeName)){
map = new HashMap<String, String>();
}
if(attributes != null && map != null){
for(int i = 0; i < attributes.getLength();i++){
map.put(attributes.getQName(i), attributes.getValue(i));
}
}
currentTag = name;
} @Override
public void characters(char[] ch, int start, int length)
throws SAXException {
//这个方法用来处理在XML文件中读到的内容
if(currentTag != null && map != null){
currentValue = new String(ch, start, length);
if(currentValue != null && !currentValue.trim().equals("") && !currentValue.trim().equals("\n")){
map.put(currentTag, currentValue);
}
}
currentTag=null;
currentValue=null;
} @Override
public void endElement(String uri, String localName, String name)
throws SAXException {
//在遇到结束标签的时候,调用这个方法
if(name.equals(nodeName)){
list.add(map);
map = null;
}
super.endElement(uri, localName, name);
}
}

输出

to:oseye.net
body:Don't forget the meeting!
from:kevin
heading:Reminder

以上并没有对API做详细讲解,具体API可参考JDK。

Java原生API操作XML的更多相关文章

  1. ZooKeeper 原生API操作

    zookeeper客户端和服务器会话的建立是一个异步的过程,也就是说在程序中,程序方法在处理完客户端初始化后立即返回(即程序继续往下执行代码,这样,在大多数情况下并没有真正的构建好一个可用会话,在会话 ...

  2. Java用DOM操作xml

    JAXP DOM方式解析XML文档实例增删改查package jiexi; import javax.xml.parsers.DocumentBuilder; import javax.xml.par ...

  3. 不使用spring的情况下用java原生代码操作mongodb数据库的两种方式

    由于更改了mongodb3.0数据库的密码,导致这几天storm组对数据进行处理的时候,一直在报mongodb数据库连接不上的异常.   主要原因实际上是和mongodb本身无关的,因为他们改的是配置 ...

  4. 读《分布式一致性原理》JAVA客户端API操作3

    更新数据 客户端可以通过zookeeper的API来更新一个节点的数据内容,有如下两个接口: public Stat setData(final String path, byte data[], i ...

  5. 读《分布式一致性原理》JAVA客户端API操作2

    创建节点 通过客户端API来创建一个数据节点,有一下两个接口: public String create(final String path, byte data[], List<ACL> ...

  6. ES的java端API操作

    首先简单介绍下写这篇博文的背景,最近负责的一个聚合型的新项目要大量使用ES的检索功能,之前对es的了解还只是纯理论最多加个基于postman的索引创建操作,所以这次我得了解在java端如何编码实现:网 ...

  7. Java原生API访问MongoDB

    1.pom.xml <dependency> <groupId>org.mongodb</groupId> <artifactId>mongo-java ...

  8. java使用DOM操作XML

    XML DOM简介 XML DOM 是用于获取.更改.添加或删除 XML 元素的标准. XML 文档中的每个成分都是一个节点. DOM 是这样规定的: 整个文档是一个文档节点 每个 XML 标签是一个 ...

  9. Zookeeper(三)-- JAVA原生API

    一.前提 jar包:zookeeper-3.4.9.jar,slf4j-api-1.6.1.jar,slf4j-log4j12-1.6.1.jar,log4j-1.2.15.jar 二.Demo pa ...

随机推荐

  1. firefox-Developer开发者站点——关于Object.create()新方法的介绍

    https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/create Objec ...

  2. MariaDB与MySQL在一台服务器同时运行

    [root@HE3 ~]#groupadd mariadb -g 513 [root@HE3 ~]#useradd-u 513 -gmariadb -s /sbin/nologin -d /home/ ...

  3. axure8.0注册码

    激活码:(亲测可用) 用户名:aaa 注册码:2GQrt5XHYY7SBK/4b22Gm4Dh8alaR0/0k3gEN5h7FkVPIn8oG3uphlOeytIajxGU 用户名:axureuse ...

  4. Promise基础

    前言: ES2015将Promise引入语言规范,包括fetch等在内的API也构建在Promise之上.作为让js摆脱“回调地狱”的重要一环和众多框架中的重要基础设施之一,学习如何自己实现一个Pro ...

  5. line-height系列——定义和工作原理总结

    一.line-height的定义和工作原理总结 line-height的属性值: normal    默认  设置合理的行间距. number  设置数字,此数字会与当前的字体尺寸相乘来设置行间距li ...

  6. Linux笔记(十三) - 系统管理

    (1)进程管理1.判断服务器健康状态2.查看进程a.查看系统中所有进程:ps    例:ps aux(使用BSD操作系统命令格式)    a 显示所有前台进程    x 显示所有后台进程    u 显 ...

  7. ASP.NET\MVC 解决C#上传图片质量下降,图片模糊,水印有杂点的问题

    对图片处理这一块不是很懂,自己写不出来,这些年一直没有停止找一个上传图片质量不下降,加水印不会导致模糊和水印周边产生杂点的代码. 网上基本上99.9%的代码处理图片质量都是下面这两句: //设置质量 ...

  8. ubuntu 笔记一

    注:ubuntu14.04 64位 1.刚安装的ubuntu无法在终端使用su 原因:root没有默认密码,需要手动设定. 解决方法:以具有sudo权限的用户登录 给root用户设置密码:打开一个te ...

  9. 阿里云oss总是提示SignatureDoesNotMatch错误怎么办

    网上的所有阿里云oss(C#)的例子几乎试遍了,为什么还是提示SignatureDoesNotMatch错误?什么原因?怎么办?下载一个阿里云提供的windows客户端发现,依然提示签名错误. 开始怀 ...

  10. PHP面向对象(OOP)----分页类

    > 同验证码类,分页也是在个人博客,论坛等网站中不可缺少的方式,通过分页可以在一个界面展示固定条数的数据,而不至于将所有数据全部罗列到一起,实现分页的原理其实就是对数据库查询输出加了一个limi ...