第二章 XML

来源:互联网 发布:js中如何定义数组 编辑:程序博客网 时间:2024/06/07 04:37

2.1简介
尽管XML和HTML同宗同源,但是两者之间存在重要的区别:

  • 与HTML不同,XML是大小写敏感
  • 在HTML中,如果从上下文可以分清哪里是段落或列表项的结尾,那么结束标签就可以省略,而在XML中结束标签绝对不能省略。
  • 在XML中,只有单个标签而没有相对应的结束标签的元素必须以/结尾。
  • 在XML中,属性值必须用引号括起来
  • 在HTML中,属性名可以没有值。在XML中,所有属性都必须有属性值。

XML文档的结构
XML文档应当以一个文档头开始,例如:

<?xml version="1.0"?>

或者

<?xml version="1.0" enconding="UTF-8"?>

但是严格的来说,文档头是可选的,但是强烈建议你使用文档头

2.2 解析XML文档
要处理XML文档,要首先解析它。解析器是这样一个程序:它读入一个文件,确认这个文件具有正确的格式,然后将其分解成各个元素,使得程序员能够访问这些元素。
Java库提供了两种XML解析器:

  • 像文档对象模型(Document Object Model,DOM)解析器这样的树型解析器,它们将读入的XML文档转换成树结构。
  • 像XML简单API(Simple API for XML,SAX)解析器这样的流机制解析器,它们在读入XML文档是生成相应的事件。

这两种解析器各有各的特点:如果你需要处理很长的文档,每个元素都关心,那么你可以用DOM解析器。但是用它生成树形结构将会消耗大量内存,或者如果你只是对某些元素感兴趣,而不关心他们的上下文,那么在这些情况下你应该考虑流机制解析器。

由于DOM解析器对于实现我们大多数目的来说都更容易一点,这一章节先介绍DOM解析器。

=================================================================
要读入一个文档,首先需要一个DocumentBuilder对象,可以从DocumentBuilderFactory中得到这个对象,例如:

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();DocumentBuilder builder = factory.newDocumentBuilder(); //这边会抛一个ParserConfigurationException异常

现在可以从文件中读入某文档。

File f = new File("xxx.xml");Document doc = builder.parse(f);

或者可以用一个URL:

URL u = new URL("d:\\xxxx");Document doc = builder.parse(u);

甚至可以指定一个任意的输入流:

InputStream in = new FileInputStream(new File("xxx.xml"));Document doc = builder.parse(in);

可以通过调用getDocumentElement方法来启动对文档内容的分析,它将返回根元素。

Element root = doc.getDocumentElement();

那么,调用root.getTagName()方法可以返回根元素的标签名
如果要得到该元素的子元素(可能是子元素、文本、注释或其他节点),请使用getChildNodes方法,这个方法返回一个NodeList集合。这个类型在标准的Java集合类创建之前就存在了,它有一个不同的访问协议;item方法将得到指定索引值的项;getLength方法则提供了项的总数。可以像这样枚举所有子元素:

NodeList children = root.getChildNodes();for (int i = 0; i < children.getLength(); i++) {    Node child = children.item(i);    System.out.println(child.getNodeName());}

这边需要举个栗子,表达一下分析子元素的时候要仔细。例如:

<font>    <name>Helvetica</name>    <size>36</size></font>

预期font有两个子元素,name和size。但是,解析器会报告你有5个。

  • font和name之间的空白字符
  • name元素
  • name和size之间的空白字符
  • size元素
  • size和font之间的空白字符
    它的DOM树是这样的
    一颗简单的Dom树
    如果只希望得到子元素,忽略空白字符,那么可以这么写:
for (int i = 0; i < children.getLength(); i++) {    Node child = children.item(i);    if(child instanceof Element){        Element childElement = (Element)child;    }}