例如:生成以下的文档:
<?xml version="1.0"?>
<people>
<person>
<name>zhangsan</name>
<age>30</age>
<sex>female</sex>
</person>
</people>
在DOM生成XML内容中,所有的元素都应该由Document产生,之后再分别建立各自的关系。
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
public class DOMDemo05 {
public static void main(String[] args) throws Exception {
// 1、建立DocumentBuilderFactory
DocumentBuilderFactory factory = null;
factory = DocumentBuilderFactory.newInstance();
// 2、建立DocumentBuilder
DocumentBuilder builder = factory.newDocumentBuilder();
// 3、建力Document,将整个XML文档形成DOM树
Document doc = builder.newDocument() ;
Element peo = doc.createElement("people") ;
Element per = doc.createElement("person") ;
Element name = doc.createElement("name") ;
Element age = doc.createElement("age") ;
Element sex = doc.createElement("sex") ;
// 设置节点中的内容
name.appendChild(doc.createTextNode("zhangsan")) ;
age.appendChild(doc.createTextNode("30")) ;
sex.appendChild(doc.createTextNode("female")) ;
// 设置关系
per.appendChild(name) ;
per.appendChild(age) ;
per.appendChild(sex) ;
peo.appendChild(per) ;
doc.appendChild(peo) ;
NodeList nl = doc.getElementsByTagName("person");
Element p = (Element) nl.item(0); // 定位节点到person之中
System.out.println(p.getElementsByTagName("name").item(0)
.getFirstChild().getNodeValue());
System.out.println(p.getElementsByTagName("age").item(0)
.getFirstChild().getNodeValue());
System.out.println(p.getElementsByTagName("sex").item(0)
.getFirstChild().getNodeValue());
}
}
以上的文档都还只是在内存中形成的,可以将其通过IO操作输出到文件之中。
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
public class DOMDemo06 {
public static void main(String[] args) throws Exception {
// 1、建立DocumentBuilderFactory
DocumentBuilderFactory factory = null;
factory = DocumentBuilderFactory.newInstance();
// 2、建立DocumentBuilder
DocumentBuilder builder = factory.newDocumentBuilder();
// 3、建力Document,将整个XML文档形成DOM树
Document doc = builder.newDocument() ;
Element peo = doc.createElement("people") ;
Element per = doc.createElement("person") ;
Element name = doc.createElement("name") ;
Element age = doc.createElement("age") ;
Element sex = doc.createElement("sex") ;
// 设置节点中的内容
name.appendChild(doc.createTextNode("张三")) ;
age.appendChild(doc.createTextNode("30")) ;
sex.appendChild(doc.createTextNode("female")) ;
// 设置关系
per.appendChild(name) ;
per.appendChild(age) ;
per.appendChild(sex) ;
peo.appendChild(per) ;
doc.appendChild(peo) ;
TransformerFactory tf = TransformerFactory.newInstance() ;
Transformer f = tf.newTransformer() ;
// 设置编码
f.setOutputProperty(OutputKeys.ENCODING, "GBK") ;
// 通过DOMSource输出内容
DOMSource source = new DOMSource(doc) ;
StreamResult stream = new StreamResult("d:\\abc.xml") ;
f.transform(source, stream) ;
}
}
3.2.2、SAX解析
SAX:简单API XML解析。
使用顺序的读取方式,部分读取内容。
在使用SAX之前,首先必须建立好SAX解析器,一个类只要继承了DefaultHandler类,那么此类就可以成为SAX解析器。
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class MySAX extends DefaultHandler {
public void characters(char[] ch, int start, int length) throws SAXException {
System.out.print(new String(ch,start,length)) ;
}
public void endDocument() throws SAXException {
System.out.println("===== 文档结束 =====");
}
public void endElement(String uri, String localName, String qName) throws SAXException {
System.out.print("</"+qName+">") ;
}
public void startDocument() throws SAXException {
System.out.println("===== 文档开始 =====");
}
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
System.out.print("<"+qName+">") ;
}
}
下一步开始具体应用此解析器。
import java.io.File;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
public class SAXDemo {
public static void main(String[] args) throws Exception {
SAXParserFactory factory = null ;
factory = SAXParserFactory.newInstance() ;
SAXParser par = factory.newSAXParser() ;
par.parse(new File("d:\\demo.xml"), new MySAX()) ;
}
}
SAX解析操作的时候本身只能提供顺序的读取,但是不具备内容的修改功能。
3.2.3、JDOM
SAX和DOM都属于标准的操作接口,其本身符合W3C标准,但是因为DOM和SAX两者各有优点和缺点,所以后来开发者开发出了一套新的API —— JDOM,结合DOM的可修改性以及SAX解析的性能高的特点,形成了新的组件。
Jdom本身是一个单独开发包,jdom也需要一个jar包。
使用Jdom可以方便的生成XML文件。
<?xml version="1.0"?>
<people>
<person>
<name>zhangsan</name>
<age>30</age>
<sex>female</sex>
</person>
</people>
使用jdom生成以上的内容。
import java.io.FileOutputStream;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.output.XMLOutputter;
public class JDOMDemo01 {
public static void main(String[] args) throws Exception {
Element peo = new Element("people");
Element per = new Element("person");
Element name = new Element("name");
Element age = new Element("age");
Element sex = new Element("sex");
name.setText("zhangsan");
age.setText("30");
sex.setText("男");
// 设置关系
per.addContent(name);
per.addContent(age);
per.addContent(sex);
peo.addContent(per);
Document doc = new Document(peo);
// jdom中非常方便的就可以输出内容
XMLOutputter out = new XMLOutputter();
out.setEncoding("GBK");
out.output(doc, new FileOutputStream("d:\\d.xml"));
}
}
同样,JDOM中可以使用SAX的解析方式解析XML文件。
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;
public class JDOMDemo02 {
public static void main(String[] args) throws Exception {
SAXBuilder builder = new SAXBuilder() ;
Document doc = builder.build("d:\\d.xml") ;
Element peo = doc.getRootElement() ; // 得到根节点
System.out.println(peo.getChild("person").getChildText("name")) ;
System.out.println(peo.getChild("person").getChildText("age")) ;
System.out.println(peo.getChild("person").getChildText("sex")) ;
}
}
如果现在在一个people元素中有多个person节点,则此时就可以发现Jdom所具备的优点了。
<?xml version="1.0" encoding="GBK"?>
<people>
<person>
<name>zhangsan</name>
<age>30</age>
<sex>男</sex>
</person>
<person>
<name>lisi</name>
<age>31</age>
<sex>女</sex>
</person>
</people>
解析如下:
import java.util.Iterator;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;
public class JDOMDemo03 {
public static void main(String[] args) throws Exception {
SAXBuilder builder = new SAXBuilder() ;
Document doc = builder.build("d:\\d.xml") ;
Element peo = doc.getRootElement() ; // 得到根节点
Iterator iter = peo.getChildren().iterator() ;
while(iter.hasNext()){
Element ele = (Element)iter.next() ;
System.out.print(ele.getChildText("name")+";") ;
System.out.print(ele.getChildText("age")+";") ;
System.out.print(ele.getChildText("sex")+"\n") ;
System.out.print("=================================") ;
}
}
}
3.3、HTML中使用DOM解析
有如下的XML文件:
<?xml version="1.0" encoding="GBK"?>
<allplus>
<plus>
<id>1</id>
<title>北京</title>
</plus>
</allplus>
使用AJAX读取内容
<html>
<head>
<title>dom01.htm</title>
<script language="javaScript">
var xmlHttp ;
function createXmlHttp(){
if(window.XmlHttpRequest){
xmlHttp = new XmlHttpRequest() ;
}else{
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP") ;
}
}
function getContent(){
createXmlHttp() ;
xmlHttp.onreadystatechange = getContentCallback ;
xmlHttp.open("POST","data.xml") ;
xmlHttp.send(null) ;
}
function getContentCallback(){
if(xmlHttp.readyState==4){ // 数据已经全部读取完毕
// 从读取的内容中解析出xml文件
var root = xmlHttp.responseXML.getElementsByTagName("allplus")[0].childNodes ;
// 把内容读取出来
for(var i=0;i<root.length;i++){
var plus = root[i] ;
alert(plus.getElementsByTagName("id")[0].firstChild.nodeValue + " --> " +
plus.getElementsByTagName("title")[0].firstChild.nodeValue) ;
}
}
}
</script>
</head>
<body>
<input type="button" value="按我" onClick="getContent()">
</body>
</html>
直接通过JavaScript生成一个下拉列表框。
<html>
<head>
<title>dom01.htm</title>
<script language="javaScript">
function fun(){
var select = document.getElementById("plus") ;
select.length = 1 ; // 每次只能选择一个内容
select.options[0].selected = true ; // 第一个被默认选中
var id = 1 ;
var title = "北京" ;
var option = document.createElement("option") ;
option.setAttribute("value",id) ;
option.appendChild(document.createTextNode(title)) ;
select.appendChild(option) ;
}
</script>
</head>
<body>
<form>
<select name="plus" id="plus">
<option value="0">没有地区</option>
</select>
<input type="button" value="按我" onClick="fun()">
</select>
</body>
</html>
以上代码发现,HTML中也是可以使用DOM解析操作的。
4、总结
1、 DOM与SAX解析各自的优点及缺点
2、 灵活使用Jdom解析输出
3、 可以直接使用AJAX读取XML文件格式的内容
4、 HTML中的所有元素都可以使用DOM解析操作
5、预习任务
1、 Hibernate入门
6、作业
使用Struts + AJAX + Jdom + XML生成一个级联菜单,依然使用地区-子地区操作
• Struts中使用DAO可以取出全部的子地区,根据地区编号取
• 在Action中使用内存输出流,将所有的子地区生成一个XML风格的文件
|- 内存输入、输出流:ByteArrayOutputStream、ByteArrayInputStream
• 前台的HTML页面中可以列出全部的地区,之后地区改变,可以通过AJAX取出全部的子地区
• 子地区使用JavaScript进行DOM解析,从返回的XML文件里取出全部的内容
• 注意:所有生成的XML文件都不能以文件的形式出现。
<?xml version="1.0"?>
<people>
<person>
<name>zhangsan</name>
<age>30</age>
<sex>female</sex>
</person>
</people>
在DOM生成XML内容中,所有的元素都应该由Document产生,之后再分别建立各自的关系。
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
public class DOMDemo05 {
public static void main(String[] args) throws Exception {
// 1、建立DocumentBuilderFactory
DocumentBuilderFactory factory = null;
factory = DocumentBuilderFactory.newInstance();
// 2、建立DocumentBuilder
DocumentBuilder builder = factory.newDocumentBuilder();
// 3、建力Document,将整个XML文档形成DOM树
Document doc = builder.newDocument() ;
Element peo = doc.createElement("people") ;
Element per = doc.createElement("person") ;
Element name = doc.createElement("name") ;
Element age = doc.createElement("age") ;
Element sex = doc.createElement("sex") ;
// 设置节点中的内容
name.appendChild(doc.createTextNode("zhangsan")) ;
age.appendChild(doc.createTextNode("30")) ;
sex.appendChild(doc.createTextNode("female")) ;
// 设置关系
per.appendChild(name) ;
per.appendChild(age) ;
per.appendChild(sex) ;
peo.appendChild(per) ;
doc.appendChild(peo) ;
NodeList nl = doc.getElementsByTagName("person");
Element p = (Element) nl.item(0); // 定位节点到person之中
System.out.println(p.getElementsByTagName("name").item(0)
.getFirstChild().getNodeValue());
System.out.println(p.getElementsByTagName("age").item(0)
.getFirstChild().getNodeValue());
System.out.println(p.getElementsByTagName("sex").item(0)
.getFirstChild().getNodeValue());
}
}
以上的文档都还只是在内存中形成的,可以将其通过IO操作输出到文件之中。
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
public class DOMDemo06 {
public static void main(String[] args) throws Exception {
// 1、建立DocumentBuilderFactory
DocumentBuilderFactory factory = null;
factory = DocumentBuilderFactory.newInstance();
// 2、建立DocumentBuilder
DocumentBuilder builder = factory.newDocumentBuilder();
// 3、建力Document,将整个XML文档形成DOM树
Document doc = builder.newDocument() ;
Element peo = doc.createElement("people") ;
Element per = doc.createElement("person") ;
Element name = doc.createElement("name") ;
Element age = doc.createElement("age") ;
Element sex = doc.createElement("sex") ;
// 设置节点中的内容
name.appendChild(doc.createTextNode("张三")) ;
age.appendChild(doc.createTextNode("30")) ;
sex.appendChild(doc.createTextNode("female")) ;
// 设置关系
per.appendChild(name) ;
per.appendChild(age) ;
per.appendChild(sex) ;
peo.appendChild(per) ;
doc.appendChild(peo) ;
TransformerFactory tf = TransformerFactory.newInstance() ;
Transformer f = tf.newTransformer() ;
// 设置编码
f.setOutputProperty(OutputKeys.ENCODING, "GBK") ;
// 通过DOMSource输出内容
DOMSource source = new DOMSource(doc) ;
StreamResult stream = new StreamResult("d:\\abc.xml") ;
f.transform(source, stream) ;
}
}
3.2.2、SAX解析
SAX:简单API XML解析。
使用顺序的读取方式,部分读取内容。
在使用SAX之前,首先必须建立好SAX解析器,一个类只要继承了DefaultHandler类,那么此类就可以成为SAX解析器。
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class MySAX extends DefaultHandler {
public void characters(char[] ch, int start, int length) throws SAXException {
System.out.print(new String(ch,start,length)) ;
}
public void endDocument() throws SAXException {
System.out.println("===== 文档结束 =====");
}
public void endElement(String uri, String localName, String qName) throws SAXException {
System.out.print("</"+qName+">") ;
}
public void startDocument() throws SAXException {
System.out.println("===== 文档开始 =====");
}
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
System.out.print("<"+qName+">") ;
}
}
下一步开始具体应用此解析器。
import java.io.File;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
public class SAXDemo {
public static void main(String[] args) throws Exception {
SAXParserFactory factory = null ;
factory = SAXParserFactory.newInstance() ;
SAXParser par = factory.newSAXParser() ;
par.parse(new File("d:\\demo.xml"), new MySAX()) ;
}
}
SAX解析操作的时候本身只能提供顺序的读取,但是不具备内容的修改功能。
3.2.3、JDOM
SAX和DOM都属于标准的操作接口,其本身符合W3C标准,但是因为DOM和SAX两者各有优点和缺点,所以后来开发者开发出了一套新的API —— JDOM,结合DOM的可修改性以及SAX解析的性能高的特点,形成了新的组件。
Jdom本身是一个单独开发包,jdom也需要一个jar包。
使用Jdom可以方便的生成XML文件。
<?xml version="1.0"?>
<people>
<person>
<name>zhangsan</name>
<age>30</age>
<sex>female</sex>
</person>
</people>
使用jdom生成以上的内容。
import java.io.FileOutputStream;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.output.XMLOutputter;
public class JDOMDemo01 {
public static void main(String[] args) throws Exception {
Element peo = new Element("people");
Element per = new Element("person");
Element name = new Element("name");
Element age = new Element("age");
Element sex = new Element("sex");
name.setText("zhangsan");
age.setText("30");
sex.setText("男");
// 设置关系
per.addContent(name);
per.addContent(age);
per.addContent(sex);
peo.addContent(per);
Document doc = new Document(peo);
// jdom中非常方便的就可以输出内容
XMLOutputter out = new XMLOutputter();
out.setEncoding("GBK");
out.output(doc, new FileOutputStream("d:\\d.xml"));
}
}
同样,JDOM中可以使用SAX的解析方式解析XML文件。
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;
public class JDOMDemo02 {
public static void main(String[] args) throws Exception {
SAXBuilder builder = new SAXBuilder() ;
Document doc = builder.build("d:\\d.xml") ;
Element peo = doc.getRootElement() ; // 得到根节点
System.out.println(peo.getChild("person").getChildText("name")) ;
System.out.println(peo.getChild("person").getChildText("age")) ;
System.out.println(peo.getChild("person").getChildText("sex")) ;
}
}
如果现在在一个people元素中有多个person节点,则此时就可以发现Jdom所具备的优点了。
<?xml version="1.0" encoding="GBK"?>
<people>
<person>
<name>zhangsan</name>
<age>30</age>
<sex>男</sex>
</person>
<person>
<name>lisi</name>
<age>31</age>
<sex>女</sex>
</person>
</people>
解析如下:
import java.util.Iterator;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;
public class JDOMDemo03 {
public static void main(String[] args) throws Exception {
SAXBuilder builder = new SAXBuilder() ;
Document doc = builder.build("d:\\d.xml") ;
Element peo = doc.getRootElement() ; // 得到根节点
Iterator iter = peo.getChildren().iterator() ;
while(iter.hasNext()){
Element ele = (Element)iter.next() ;
System.out.print(ele.getChildText("name")+";") ;
System.out.print(ele.getChildText("age")+";") ;
System.out.print(ele.getChildText("sex")+"\n") ;
System.out.print("=================================") ;
}
}
}
3.3、HTML中使用DOM解析
有如下的XML文件:
<?xml version="1.0" encoding="GBK"?>
<allplus>
<plus>
<id>1</id>
<title>北京</title>
</plus>
</allplus>
使用AJAX读取内容
<html>
<head>
<title>dom01.htm</title>
<script language="javaScript">
var xmlHttp ;
function createXmlHttp(){
if(window.XmlHttpRequest){
xmlHttp = new XmlHttpRequest() ;
}else{
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP") ;
}
}
function getContent(){
createXmlHttp() ;
xmlHttp.onreadystatechange = getContentCallback ;
xmlHttp.open("POST","data.xml") ;
xmlHttp.send(null) ;
}
function getContentCallback(){
if(xmlHttp.readyState==4){ // 数据已经全部读取完毕
// 从读取的内容中解析出xml文件
var root = xmlHttp.responseXML.getElementsByTagName("allplus")[0].childNodes ;
// 把内容读取出来
for(var i=0;i<root.length;i++){
var plus = root[i] ;
alert(plus.getElementsByTagName("id")[0].firstChild.nodeValue + " --> " +
plus.getElementsByTagName("title")[0].firstChild.nodeValue) ;
}
}
}
</script>
</head>
<body>
<input type="button" value="按我" onClick="getContent()">
</body>
</html>
直接通过JavaScript生成一个下拉列表框。
<html>
<head>
<title>dom01.htm</title>
<script language="javaScript">
function fun(){
var select = document.getElementById("plus") ;
select.length = 1 ; // 每次只能选择一个内容
select.options[0].selected = true ; // 第一个被默认选中
var id = 1 ;
var title = "北京" ;
var option = document.createElement("option") ;
option.setAttribute("value",id) ;
option.appendChild(document.createTextNode(title)) ;
select.appendChild(option) ;
}
</script>
</head>
<body>
<form>
<select name="plus" id="plus">
<option value="0">没有地区</option>
</select>
<input type="button" value="按我" onClick="fun()">
</select>
</body>
</html>
以上代码发现,HTML中也是可以使用DOM解析操作的。
4、总结
1、 DOM与SAX解析各自的优点及缺点
2、 灵活使用Jdom解析输出
3、 可以直接使用AJAX读取XML文件格式的内容
4、 HTML中的所有元素都可以使用DOM解析操作
5、预习任务
1、 Hibernate入门
6、作业
使用Struts + AJAX + Jdom + XML生成一个级联菜单,依然使用地区-子地区操作
• Struts中使用DAO可以取出全部的子地区,根据地区编号取
• 在Action中使用内存输出流,将所有的子地区生成一个XML风格的文件
|- 内存输入、输出流:ByteArrayOutputStream、ByteArrayInputStream
• 前台的HTML页面中可以列出全部的地区,之后地区改变,可以通过AJAX取出全部的子地区
• 子地区使用JavaScript进行DOM解析,从返回的XML文件里取出全部的内容
• 注意:所有生成的XML文件都不能以文件的形式出现。