xml在java应用相当广泛,是各种框架配置文件的首先载体,典型的SSH架构如果没有xml, 。。。。。。
下面就分析一下java是如何解析xml的。
先说一下DTD(document type definition),它为文档结构制定了一套规则。
常用的是对ELEMENT和ATTLIST的定义,
ELEMENT的定义为: <!ELEMENT menu (item)*> 即menu元素包含0或多个item元素
内容的规则如下:
E* 0或多个E
E+ 1或多个E
E? 0或1个E
E1|E2|E3.....|En n个元素中的一个
E1,E2,E3,.....,En n个元素按顺序排列
#PCDATA 文本
(#PCDATA|E1|E2|....|En)* 0或多个任意顺序的文本或元素
ANY 允许任意子元素
EMPTY 不允许有子元素
--------------------------------------------------------------------------------
ATTLIST的定义为: <!ATTLIST element attribute_name type default > 即element名,属性名,类型,默认值
内容的规则如下:
类型 含义
CDATA 任意的字符串
(A1|A2|A3|....|An) 多个A之一
NMTOKEN,NMTOKENS 1或多个名字标记
ID 一个唯一的ID
IDREF,IDREFS 1或多个唯一ID的引用
ENTITY,ENTITIES 1或多个未经解析的实体
…………………… ……………………
默认值 含义
#REQUIRED 属性是必须的
#IMPLIED 属性是可选的
A 属性是可选的,若未指定,解析器报告的属性的是A
#FIXED A 属性只能是A,不管有没有指定
以school.dtd为例;
<?xml version="1.0" encoding="UTF-8"?>
<!ELEMENT school (class*)>
<!ELEMENT class (grade, count, teacher?)>
<!ELEMENT grade (#PCDATA)>
<!ELEMENT count (#PCDATA)>
<!ELEMENT teacher (#PCDATA)>
<!ATTLIST class
type (big | small | normal) "normal"
autoextend (true | false) "true"
>
对应的xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE school SYSTEM "E:\NEUSOFT\学习资料\XML\school.dtd">
<school>
<class type="big" autoextend="true">
<grade>3</grade>
<count>50</count>
<teacher>wang</teacher>
</class>
<class autoextend="true">
<grade>2</grade>
<count>40</count>
</class>
</school>
其中 class的type和autoextend属性默认值是"big","true",子元素teacher为可选
dtd文件在xml中的声明有两种方式,一种是如上所示的 system 声明,还有一种用public声明的方式
如:<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
关于属性的设置,一个通常的经验法则是只在作为修改值的解释时使用,而不是在指定值时使用。不过也有其他的法则,如hibernate把参数主要定义为属性,html中把不显示在网页上的定义为属性,等等,可以根据自己的需要定义。
java库提供了两种解析器:DOM(Document Object model)和SAX(Simple API for Xml)
以DOM为例:
package com.java.xml;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
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.w3c.dom.Text;
import org.xml.sax.SAXException;
public class ParseSchool {
/**
* @param args
* void
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
ParseSchool ps = new ParseSchool();
try {
ps
.parseXMLSchool("E:/Workspace/javaTest/src/com/java/xml/school.xml");
} catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public Document getDocument(String url)
throws ParserConfigurationException, SAXException, IOException {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setValidating(true); // 打开dtd验证
factory.setIgnoringElementContentWhitespace(true);// 忽略空白符
factory.setIgnoringComments(true); // 忽略注释
DocumentBuilder builder = factory.newDocumentBuilder();
File f = new File(url);
return builder.parse(f);
}
public void parseXMLSchool(String url) throws ParserConfigurationException,
SAXException, IOException {
Document document = getDocument(url);
Element root = document.getDocumentElement();
System.out.println("root element :" + root.getTagName());
NodeList children = root.getChildNodes(); // 取得子元素列表
for (int i = 0; i < children.getLength(); i++) {
Element element = (Element) (children.item(i));
System.out.println(element.getTagName() // 取得element的attributes
+ ": type=" + element.getAttribute("type")
+ " autoextend:"
+ element.getAttribute("autoextend"));
NodeList children2 = element.getChildNodes();
for (int j = 0; j < children2.getLength(); j++) {
Node node = children2.item(j); // 分别读取子元素
Element element2 = (Element) node;
Text t = (Text) node.getFirstChild(); // element
// 的文本内容是下一个字元素,获取后将其(node)转换成Text
System.out.println(element2.getTagName() + ":" + t.getData());
}
}
}
}
运行结果为:
root element :school
class: type=big autoextend:true
grade:3
count:50
teacher:wang
class: type=normal autoextend:true
grade:2
count:40
使用XPath来定位信息,代码如下:
public void testXPath(Document document) throws XPathExpressionException {
XPathFactory xPathFactory = XPathFactory.newInstance(); // 创建XPathFactory
XPath xPath = xPathFactory.newXPath(); // 实例化XPath
String count = xPath.evaluate("/school/class[1]/count", document); // 取得子元素count值
String classType = xPath.evaluate("/school/class[1]/@type", document);// 取得属性type的值
int classNum = ((Number) xPath.evaluate("count(school/class)",
document, XPathConstants.NUMBER)).intValue(); // 取得子元素class的个数,使用了XPathConstants提供的属性参数
System.out.println("class[1]: count = " + count + ",classtype="
+ classType);
System.out.println("classNum=" + classNum);
Node class1Node = (Node) xPath.evaluate("/school/class[1]", document,
XPathConstants.NODE); // 取得第一个class
String countOfClass1 = xPath.evaluate("/school/class[2]/count", class1Node); // 直接从class1Node中取值,/表示树根部位
System.out.println("count of class2 =" + countOfClass1);
}
关于红色部分,class1Node节点应该存放第一个class的信息,但是可以从中取到第二个class的count值。用debug查看其对象信息,里面的信息很乱,没有的看出什么结果,希望明白这一块的朋友给与指点,^~^.
DOM解析器读入的是一个完整的xml文档,对于大多数应用DOM都运行的很好,但是如果文档很大,就显得效率低下了。
SAX解析器在解析xml输入的构件时报告事件,但不会对文档进行存储,DOM就是在SAX基础上建立起来的。主要就是对
SAXParser类parse(source,handler)方法中handler的重写。
DOM4J是一个使用相当广泛的xml解析工具,hibernate就使用它来解析xml的,用起来也比较简单。
官方网站: http://www.dom4j.org/
学习资料连接:http://www-128.ibm.com/developerworks/cn/xml/x-dom4j.html
分享到:
相关推荐
JAVA 解析XML和生成XML文档源码。比较全 1.DOM生成和解析XML文档 2.SAX生成和解析XML文档 3.DOM4J生成和解析XML文档 4.JDOM生成和解析XML
### Java解析XML字符串 在给定的代码示例中,我们看到了如何使用JDOM库来解析一个XML字符串,并对其进行操作。下面我们将详细解析这个过程: 1. **初始化XML源**:首先,将XML字符串转化为`StringReader`对象,这...
Java解析XML文件是Java开发中常见的一项任务,XML(eXtensible Markup Language)作为一种结构化数据存储格式,被广泛用于数据交换、配置文件和Web服务等场景。本篇文章将详细探讨Java如何利用DOM4J库来解析XML文件...
本教程将介绍如何使用Java解析XML文件,并将解析结果导入MySQL数据库。 首先,我们需要引入处理XML的Java库——JAXB(Java Architecture for XML Binding)和DOM(Document Object Model)API。JAXB用于对象与XML...
### JAVA解析XML知识点详解 #### 一、XML与JAVA的关系 **XML (eXtensible Markup Language)** 是一种用于标记电子文件使其具有结构性的标记语言。由于其平台无关性、语言无关性和系统的无关性,XML成为了数据交换...
以下是一个简单的DOM解析XML的例子: ```java import javax.xml.parsers.*; import org.w3c.dom.*; import java.io.*; public class DOMExample { public static void main(String[] args) { try { ...