Char2 XML

解析器:读入一个文件,确认其具有正确的格式,然后将其分解成各种元素,使程序员能够访问这些元素。

java库提供了两种XML解析器:DOM和SAX,即文档对象模型和流机制解析器。

DOM不适合处理太长的XML,考虑到内存的消耗。

如果只对XML中的某些元素感兴趣,而不关心上下文,考虑用SAX。

DOM解析器的接口已经被W3C标准化了,org.w3c.dom包中包含了这些接口类型的定义,比如Document和Element等。不同的组织都提供了实现这些接口的DOM解析器,如Apache和IBM。我们可以通过JAXP(Java API for XML Processing)库以插件的方式使用这些解析器中的任意一个。JDK本身也有自己的DOM解析器。本章就使用这个。所以,我们只要通过实现以上的接口或类就能达到使用解析器的目的。

以下是读入一个XML文档的方式:

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

DocumentBuilder builder = factory.newDocumentBuilder();  //这个就是解析器对象啦

书里说了三种XML的来源,File、URL、InputStream:

FIle f = ...

Document doc = builder.parse(f);

URL u = ...

Document doc = builder.parse(u);

InputStream in = ...

Document doc = builder.parse(in);

需要注意的是,如果以InputStream为输入源,当XML中有用到DTD等以该XML的位置为相对路径的引用时,解析器将无法定位这个DTD等文档。需要安装一个“实体解析器”(entity resolver)来解决这个问题。

接下来就是解析Document对象各个部分的事了,具体看这个图:

例如,处理下面的文档:

<?xml version="1.0"?>

<font>

<name>Zhangsan</name>

<size>33</size>

</font>

Element root = doc.getDocumentElement();  //返回根元素font

root.getTagName();   //返回字符串"font"

获得该元素的子元素:

NodeList children = root.getChildNodes();

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

Node child = children.item(i);

...

}

其中,getLength()=5而不是2,为啥?因为子元素与主元素之间、子元素与子元素之间空格也算了。如果只希望得到子元素,可以这样处理:

NodeList children = root.getChildNodes();

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

Node child = children.item(i);

if(child instanceof Element){

Element childElement = (Element)child;

...

}

}

这样处理还是很麻烦的,这就是为啥后面要引入DTD的原因了,DTD能后对XML的内容进行规范处理,减少一些不必要的验证过程。

我们看上面的图,其中包括空白子元素,是Text类型的,另外,发现没?name和size的值也是Text类型的,所以,怎么样获得Zhangsan、33这两个值呢?自然通过Text类型的对象来处理:

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

Node child = children.item(i);

if(child instanceof Element){

Element childElement = (Element) child;

Text textNode = (Text) childElement.getFirstChild();

String text = textNode.getData().trim();

if(childElement.getTagName().equals("name")){

name = text;

}else if(childElement.getTagName().equals(size")){

size = Integer.parseInt(text);

}

}

}

上面用到trim()是为了避免下面格式产生的空格:

<size>

33

</size>

这种情况下,解析器会把所有的换行符和空格都包含到Text中去。

最后一部分是获取XML中元素属性对象,直接上代码:

NameNodeMap attributes = element.getAttributes();

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

  Node attribute = attributes.item(i);

  String name = attribute.getNodeName();    //属性名

  String value = attribute.getNodeValue();     //属性值

}

Java核心技术II读书笔记(一)的更多相关文章

  1. Java核心技术II读书笔记(三)

    ch2 XML SAX解析器 SAXParserFactory factory = SAXParserFactory.newInstance(); SAXParser parser = factory ...

  2. Java核心技术II读书笔记(二)

    ch2 XML 有两种XML文档结构,DTD和Schema,用解释文档构成规则,这些规则指定了每个元素俺的合法子元素和属性. DTD DTD有多种提供方式,可以像下面这样加到XML中: <?xm ...

  3. 《Java核心技术》 -- 读书笔记 ② - 类 | 对象 | 接口

    对象vs对象变量 “对象” 描述的是一个类的具体实例,他被java虚拟机分配在 "堆" (Heap)中. “对象变量” 为一个对象的引用(对象变量的值=记载着具体对象的位置/地址) ...

  4. 《Java核心技术》 -- 读书笔记 ① - 预热

    引言 之前通过网上的实例自己使用了Java的一些技术及轮子快速的的“烂“造了一些小应用,但是毕竟没有认真地了解和认知Java,遂打算花一个月左右的时间来细细品味一下... 从头开始,慢慢深入!! Ja ...

  5. 《深入java虚拟机》读书笔记之垃圾收集器与内存分配策略

    前言 该读书笔记用于记录在学习<深入理解Java虚拟机--JVM高级特性与最佳实践>一书中的一些重要知识点,对其中的部分内容进行归纳,或者是对其中不明白的地方做一些注释.主要是方便之后进行 ...

  6. JAVA编程思想读书笔记(五)--多线程

    接上篇JAVA编程思想读书笔记(四)--对象的克隆 No1: daemon Thread(守护线程) 参考http://blog.csdn.net/pony_maggie/article/detail ...

  7. JAVA编程思想读书笔记(四)--对象的克隆

    接上篇JAVA编程思想读书笔记(三)--RTTI No1: 类的克隆 public class MyObject implements Cloneable { int i; public MyObje ...

  8. JAVA编程思想读书笔记(三)--RTTI

    接上篇JAVA编程思想读书笔记(二) 第十一章 运行期类型判定 No1: 对于作为程序一部分的每个类,它们都有一个Class对象.换言之,每次写一个新类时,同时也会创建一个Class对象(更恰当的说, ...

  9. JAVA编程思想读书笔记(二)--容器

    接上篇JAVA编程思想读书笔记(一) 第八章.对象的容纳 No1: java提供了四种类型的集合类:Vector(矢量).BitSet(位集).Stack(堆栈).Hashtable(散列表) No2 ...

随机推荐

  1. poj 2449(A*求第K短路)

    题目链接:http://poj.org/problem?id=2449 思路:我们可以定义g[x]为源点到当前点的距离,h[x]为当前点到目标节点的最短距离,显然有h[x]<=h*[x](h*[ ...

  2. x64的调用约定

    在设计调用约定时,x64 体系结构利用机会清除了现有 Win32 调用约定(如 __stdcall.__cdecl.__fastcall._thiscall 等)的混乱.在 Win64 中,只有一个本 ...

  3. springmvc的系统学习之配置方式

    资源:尚学堂  邹波 springmvc框架视频  一.springMVC 工作流程        页面请求---->控制器(Controller DispatcherServlet)----& ...

  4. MakeObjectInstance的前世今生(关键是ECX的何时入栈以及Self指针何时存储的)

    高手们的文章有很大启发,但是总有些小错,也有没交代清楚的,以下是我的理解: 编译器编译MainWndProc的时候,它是一个正常Delphi普通函数,MakeObjectInstance对它做变换是运 ...

  5. DP 子序列问题

    函数lower_bound()在first和last中的前闭后开区间进行二分查找,返回大于或等于val的第一个元素位置.如果所有元素都小于val,则返回last的位置举例如下:一个数组number序列 ...

  6. iOS 消息转发

    消息转发   delegate和protocol   类别      消息转发   当向someObject发送某消息,但runtime system在当前类和父类中都找不到对应方法的实现时,runt ...

  7. CentOS7安装配置Apache HTTP Server

    RPM安装httpd 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 # yum -yinstall http ...

  8. Linux 下sleep()函数

    调试程序发现起了一个子线程后,主线程上的sleep不生效了,看到这才明白... — Function: unsigned int sleep (unsigned int seconds) The sl ...

  9. OkHttp使用进阶(译自OkHttp官方教程)

    没有使用过OkHttp的,可以先看OkHttp使用介绍 英文版原版地址 Recipes · square/okhttp Wiki 同步get 下载一个文件,打印他的响应头,以string形式打印响应体 ...

  10. 新环境配置与使用Vim指南

    1.下载源码 git clone git@github.com:vim/vim.git 2.编译 1.安装依赖软件 sudo apt-get install libncurses5-dev libgn ...