XML解析之JAXP
body, table{font-family: 微软雅黑; font-size: 10pt}
table{border-collapse: collapse; border: solid gray; border-width: 2px 0 2px 0;}
th{border: 1px solid gray; padding: 4px; background-color: #DDD;}
td{border: 1px solid gray; padding: 4px;}
tr:nth-child(2n){background-color: #f8f8f8;}
DOM编程 | Node对象 |
█ DOM模型(document object model)
☞DOM解析器在解析XML文档时,会把文档中的所有元素,按照其出现的层次关系,解析成一个个Node对象(节点) document 。
☞在dom中,节点之间关系如下:
•位于一个节点之上的节点是该节点的父节点(parent)
•一个节点之下的节点是该节点的子节点(children)
•同一层次,具有相同父节点的节点是兄弟节点(sibling)
•一个节点的下一个层次的节点集合是节点后代(descendant)
•父、祖父节点及所有位于节点上面的,都是节点的祖先(ancestor)
|
█ Node对象提供了一系列常量来代表结点的类型,当开发人员获得某个Node类型后,就可以把Node节点转换成相应的节点对象(Node的子类对象),以便于调用其特有的方法。(查看API文档)
█ Node对象提供了相应的方法去获得它的父结点或子结点。编程人员通过这些方法就可以读取整个XML文档的内容、或添加、修改、删除XML文档的内容了。
|
1、得到某个具体的节点内容
2、打印某节点的所有元素节点
|
3、修改某个元素节点的主体内容
4、向指定元素节点中增加子元素节点
|
5、向指定元素节点上增加同级元素节点
6、删除指定元素节点
7、操作XML文件属性
|
█ javax.xml.transform包中的Transformer类用于把代表XML文件的Document对象转换为某种格式后进行输出,例如把xml文件应用样式表后转成一个html文档。利用这个对象,当然也可以把Document对象又重新写入到一个XML文件中。
█ Transformer类通过transform方法完成转换操作,该方法接收一个源和一个目的地。我们可以通过:
• javax.xml.transform.dom.DOMSource类来关联要转换的document对象,
• 用javax.xml.transform.stream.StreamResult 对象来表示数据的目的地。
█ Transformer对象通过TransformerFactory获得。
|
//jaxp dom解析的标准写回流程
TransformerFactory tsf =TransformerFactory.newInstance();
Transformer tsTransformer = tsf.newTransformer();
tsTransformer.transform(
new DOMSource(document),
new StreamResult("src/books.xml"));
|
Books.xml | JAXPDomPaser.java |
<?xml version="1.0" encoding="utf-8" ?>
<书架>
<书>
<书名 id="001">浪潮之巅</书名>
<作者>吴军</作者>
<售价>29</售价>
</书>
<书>
<书名 id='002'>数学之美</书名>
<作者>吴军</作者>
<售价><第一版>29</第一版></售价>
</书>
</书架>
|
package com.java.xmldom;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
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;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
|
public class JAXPDomPaser {
public static void main(String[] args) throws Exception { //真正开发中不能使用
//多态,返回的是内部实现的一个子类的实例;DOM解析器的工厂
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
//DOM解析器对象
DocumentBuilder documentBuilder=dbf.newDocumentBuilder();
//绝对路径和相对路径都可以;拿到文档对象模型:DOM树;DOM对象
Document document=documentBuilder.parse("Books.xml");
//解析流程
|
//1、得到某个具体的节点内容 得到第一本书的书名
NodeList booknameList = document.getElementsByTagName("书名");
System.out.println("JAXDomPaser.main()"+booknameList.getLength());
Node bookname1=booknameList.item(0);
short nodeType=bookname1.getNodeType(); //元素节点,节点类型=1
String nodeName = bookname1.getNodeName();
String nodeValue = bookname1.getNodeValue();
String textContent=bookname1.getTextContent();
System.out.println("JAXPDomPaser.main() "+ nodeType + nodeName + nodeValue+textContent);
|
//打印某节点的所有元素节点 ,第二个节点
NodeList bookList = document.getElementsByTagName("书");
//拿到第二本书
Node book2=bookList.item(1);
NodeList childNodes=book2.getChildNodes(); //这里空格也算一个子节点;
System.out.println("第二本书的子元素个数:"+childNodes.getLength());
for(int i=0;i<childNodes.getLength();++i){
if(childNodes.item(i).getNodeType()==1){
String childnodename = childNodes.item(i).getNodeName();
System.out.println("JAXPDomPaser.main () "+childnodename);
}
}
|
//修改某个元素节点的主体内容,把第一本书的作者改成梅浩
Node book1=bookList.item(0);
book1.getChildNodes().item(3).setTextContent("梅浩"); //这里要写回XML才会生效
|
//向指定元素节点上增加同级元素节点
Element newElement=document.createElement("销量"); //这里注意,新建的元素只有一个,添加完就没有了;比如给每个学生添加一个性别属性,用for循环添加,最只会把新建的节点添加到最后一个for循环满足添加的节点,然后写入xml
newElement.setTextContent("1000");
book1.appendChild(newElement);
|
//删除指定元素节点
Node shoujianode=document.getElementsByTagName("售价").item(0);
book1.removeChild(shoujianode);
|
//操作XML文件属性
String xmlEncoding=document.getXmlEncoding();
String version=document.getXmlVersion();
boolean standalong=document.getXmlStandalone();
System.out.println("xml encoding: "+xmlEncoding+"; xml version: "+version+"; xml standalong: "+standalong);
|
//把内存中的dom树输出到磁盘中的文档的标准写法;只有增加、修改才会写入
TransformerFactory tsf =TransformerFactory.newInstance();
Transformer tsTransformer = tsf.newTransformer();
tsTransformer.transform(
new DOMSource(document),
new StreamResult("src/Books.xml"));
}
}//xml会重新保存在src下
|
//事件处理器有一个缺省的DefaultHandler |
//方法步骤
☞使用SAXParserFactory创建SAX解析工厂
SAXParserFactory spf = SAXParserFactory.newInstance();
☞通过SAX解析工厂得到解析器对象
SAXParser sp = spf.newSAXParser();
☞通过解析器对象得到一个XML的读取器
XMLReader xmlReader = sp.getXMLReader();
☞设置读取器的事件处理器
xmlReader.setContentHandler(new BookParserHandler());
☞解析xml文件
xmlReader.parse("book.xml");
|
Books.xml | MySaxParseDemo.java |
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<书架>
<书>
<书名 id="001">浪潮之巅</书名>
<作者>梅浩</作者>
</书>
<书>
<书名 id="002">数学之美</书名>
<作者>吴军</作者>
<售价><第一版>29</第一版></售价>
</书>
</书架>
|
package com.java.xml_sax;
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;
public class MySaxParseDemo {
public static void main(String[] args) throws Exception {
|
SAXParserFactory spf=SAXParserFactory.newInstance();
SAXParser saxParser=spf.newSAXParser();
MySaxhandler mySaxHandler=new MySaxhandler();
// parse(String uri, DefaultHandler dh)
//Parse the content described by the giving Uniform Resource Identifier (URI) as XML using the specified
//使用指定的 DefaultHandler 将给定统一资源标识符 (URI) 描述的内容解析为 XML。
saxParser.parse("Books.xml",mySaxHandler);
//调用这个方法要传递一个缺省DefaultHandler dh ,我们要自己写一个类来重写这个方法
}
}
|
class MySaxhandler extends DefaultHandler{ //定义自己的类来重写方法
//写好类名和继承,右键-源码-覆盖/实现方法选择要覆盖的方法
int count=0; //统计书名出现的次数,经常用这种方法来设置输出制定信息
public void startDocument() throws SAXException {
super.startDocument();
System.out.println("MySaxHandler.startDocument()!文档开始");
}
public void endDocument() throws SAXException {
super.endDocument();
System.out.println("MySaxHandler.endDocument()!文档解析结束");
}
|
public void startElement(String arg0, String arg1, String arg2, Attributes arg3) throws SAXException {
super.startElement(arg0, arg1, arg2, arg3); //鼠标放上面可以自动显示父类对应的参数名,应该是版本问题不能关联源代码。不然的话就不会显示arg了,那样可以直观看出每个参数的表示意义:startElement(String uri, String localName, String qName, Attributes attributes)
System.out.println("MySaxHandler.startElement()!元素 "+arg2+" 节点开始");
if(arg2=="书名"){
String value=arg3.getValue("id"); //通过属性名查找属性值
String value1=arg3.getValue(0); //通过属性的次序查找属性值,书名里面第0个属性值
System.out.println("id= "+value);
System.out.println("id1= "+value1);
}
if(arg2=="书名"){ //标记第二本书
count++;
}
}
public void endElement(String arg0, String arg1, String arg2) throws SAXException {
//endElement(String uri, String localName, String qName)
super.endElement(arg0, arg1, arg2);
System.out.println("MySaxHandler.endElement()!元素 "+arg2+" 节点闭合");
}
|
public void characters(char[] arg0, int arg1, int arg2) throws SAXException {
//characters(char[] ch, int start, int length)
if(2==count){ //当前是第二本书的时候
String content = new String(arg0, arg1, arg2);
System.out.println("MySaxHandler.characters()!文本节点" + content);
count=-1; //修改变量,不然后面的都会输出
}
super.characters(arg0, arg1, arg2);
/*String content = new String(arg0, arg1, arg2);
System.out.println("MySaxHandler.characters()!文本节点" + content);*/
}
}
|
SAX方式解析XML文档:
1、使用SAXParserFactory创建SAX解析工厂
SAXParserFactory spf = SAXParserFactory.newInstance();
2、通过SAX解析工厂得到解析器对象
SAXParser sp = spf.newSAXParser();
3、通过解析器对象得到一个XML的读取器
XMLReader xmlReader = sp.getXMLReader();
4、设置读取器的事件处理器
xmlReader.setContentHandler(new BookParserHandler());
5、解析xml文件
xmlReader.parse("book.xml");
|
|
cd.xml | sax.xml |
<?xml version="1.0" encoding="UTF-8"?>
<CATALOG>
<CD>
<TITLE>Empire Burlesque</TITLE>
<ARTIST>Bob Dylan</ARTIST>
<COUNTRY>USA</COUNTRY>
<COMPANY>Columbia</COMPANY>
<PRICE>10.90</PRICE>
<YEAR>1985</YEAR>
</CD>
<CD>
<TITLE>Hide your heart</TITLE>
<ARTIST>Bonnie Tyler</ARTIST>
<COUNTRY>UK</COUNTRY>
<COMPANY>CBS Records</COMPANY>
<PRICE>9.90</PRICE>
<YEAR>1988</YEAR>
</CD>
<CD>
<TITLE>Greatest Hits</TITLE>
<ARTIST>Dolly Parton</ARTIST>
<COUNTRY>USA</COUNTRY>
<COMPANY>RCA</COMPANY>
<PRICE>9.90</PRICE>
<YEAR>1982</YEAR>
</CD>
<CD>
<TITLE>Still got the blues</TITLE>
<ARTIST>Gary Moore</ARTIST>
<COUNTRY>UK</COUNTRY>
<COMPANY>Virgin records</COMPANY>
<PRICE>10.20</PRICE>
<YEAR>1990</YEAR>
</CD>
<CD>
<TITLE>Eros</TITLE>
<ARTIST>Eros Ramazzotti</ARTIST>
<COUNTRY>EU</COUNTRY>
<COMPANY>BMG</COMPANY>
<PRICE>9.90</PRICE>
<YEAR>1997</YEAR>
</CD>
<CD>
<TITLE>One night only</TITLE>
<ARTIST>Bee Gees</ARTIST>
<COUNTRY>UK</COUNTRY>
<COMPANY>Polydor</COMPANY>
<PRICE>10.90</PRICE>
<YEAR>1998</YEAR>
</CD>
</CATALOG>
程序结果: |
//导入包什么的没有放入笔记
public class sax {
public static void main(String[] args) throws Exception{
//使用SAXParserFactory创建SAX解析工厂
SAXParserFactory spf=SAXParserFactory.newInstance();
//通过SAX解析工厂得到解析器对象
SAXParser sp=spf.newSAXParser();
//通过解析器对象得到一个XML的读取器
XMLReader reader=sp.getXMLReader();
//设置读取器的事件处理器
MySaxhandler mySaxHandler=new MySaxhandler();
reader.setContentHandler(mySaxHandler);
//解析xml文件
reader.parse("cd.xml");
}
}
class MySaxhandler extends DefaultHandler{
String tagName;
public int i=0;
public int j=0;
public String[] artist = new String[6]; //记录所有ARTIST
public String[] country = new String[6]; //记录所有COUNTRY
public Boolean ta=false; //标记artist是读到元素开始还是元素结束
public Boolean tc=false; //标记country是读到元素开始还是元素结束
public void startElement(String uri, String localName,String qName, Attributes attributes) throws SAXException {
tagName=qName; //将读取到的标签名赋给tagName
if(tagName.equals("ARTIST")){
ta=true; //标记ARTIST是开始
}
if(tagName.equals("COUNTRY")){
tc=true; //标记ARTIST是结束
}
}
public void characters(char[] ch, int start, int length)throws SAXException {
String name=new String(ch, start, length); //拼接出每次的文本
if(tagName.equals("ARTIST")&& ta==true){ //如果读到ARTIST的开始,那么后面的文本就是我们要的,要存起来
ta=false; //记录完,后面读到的肯定是元素结束,这里事先标记
artist[i++]=name; //记录ARTIST
}
if(tagName.equals("COUNTRY")&&tc==true){
tc=false;
country[j++]=name;
}
}
public void endElement(String uri, String localName, String qName)throws SAXException {
tagName=qName;
if(tagName.equals("ARTIST")){
ta=false; //再次赋值为0,确保正确
}
if(tagName.equals("COUNTRY")){
tc=false;
}
}
public void endDocument() throws SAXException {
for(int k=0;k<j;k++){
if(country[k].equals("UK")){
System.out.println("MySaxDemo.main characters() "+artist[k]);
}
}
}
}
|
XML解析之JAXP的更多相关文章
- XML 解析之 jaxp 解析器
XML 的解析方式有两种方式: DOM 解析和 SAX 解析. DOM 解析: 根据 XML 的层级结构, 在内存中分配一个树形结构, 把 XML 的标签, 属性和文本都封装成对象. 优点: 可以实现 ...
- XML解析器之JAXP与DOM4J
XML是一种数据格式,那么需要对XML文件进行操作就需要用到XML解析器---------针对dom方式和sax方式提供了不同的解析技术-----需要不同的XML解析器 dom方式:会把文档中所有元素 ...
- XML解析之JAXP案例详解
根据一个CRUD的案例,对JAXP解析xml技术,进行详细的解释: 首先,已知一个xml文件中的数据如下: <?xml version="1.0" encoding=&quo ...
- XML概念定义以及如何定义xml文件编写约束条件java解析xml DTD XML Schema JAXP java xml解析 dom4j 解析 xpath dom sax
本文主要涉及:xml概念描述,xml的约束文件,dtd,xsd文件的定义使用,如何在xml中引用xsd文件,如何使用java解析xml,解析xml方式dom sax,dom4j解析xml文件 XML来 ...
- JAVA基础学习之XMLCDATA区、XML处理指令、XML约束概述、JavaBean、XML解析(8)
1.CDATA区在编写XML文件时,有些内容可能不想让解析引擎解析执行,而是当作原始内容处理.遇到此种情况,可以把这些内容放在CDATA区里,对于CDATA区域内的内容,XML解析程序不会处理,而是直 ...
- XML解析【介绍、DOM、SAX详细说明、jaxp、dom4j、XPATH】
什么是XML解析 前面XML章节已经说了,XML被设计为"什么都不做",XML只用于组织.存储数据,除此之外的数据生成.读取.传送等等的操作都与XML本身无关! XML解析就是读取 ...
- xml解析方式之JAXP解析入门
XML解析 1 引入 xml文件除了给开发者看,更多的情况使用[程序读取xml文件]的内容.这叫做xml解析 2 XML解析方式(原理不同) DOM解析 SAX解析 3 XML解析工具 DOM解析原理 ...
- Java XML解析工具 dom4j介绍及使用实例
Java XML解析工具 dom4j介绍及使用实例 dom4j介绍 dom4j的项目地址:http://sourceforge.net/projects/dom4j/?source=directory ...
- 【Java】XML解析之DOM4J
DOM4J介绍 dom4j是一个简单的开源库,用于处理XML. XPath和XSLT,它基于Java平台,使用Java的集合框架,全面集成了DOM,SAX和JAXP,使用需要引用dom4j.jar包 ...
随机推荐
- 【Coursera】Technology :Fifth Week(1)
Store and Forward Networking 在长途连接中,路由的数量 取决于 最优路径(花费最少).也就是说被地理条件所限制. 所以 Store and Forward Networki ...
- samba基本应用24-4及示例
samba smb:service message block(137/udp, 138/udp, 139/tcp, 445/tcp) 协议是:CIFS:Common Internet File Sy ...
- 【BZOJ】4012: [HNOI2015]开店
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=4012 给出一个$n$个点的树,树上每一个点都有一个值$age$,每条边都有边权,每次查询一 ...
- testNG 学习笔记 Day 3 常用的断言
TestNG中最常用的一个断言类是Assert.java,里面有多个静态方法,这个类我们习惯叫硬断言.对应的还有一个软断言的类,叫SoftAssert.java,这个类是需要创建实例对象,才能调用相关 ...
- django关系类型字段
一.多对一(ForeignKey) 多对一的关系,通常被称为外键.外键字段类的定义如下: class ForeignKey(to, on_delete, **options)[source] 外键需要 ...
- 【Golang 接口自动化03】 解析接口返回XML
上一篇我们学习了怎么发送各种数据类型的http请求,这一篇我们来介绍怎么来解析接口返回的XML的数据. 解析接口返回数据 定义结构体 假设我们现在有一个接口返回的数据resp如下: <?xml ...
- RabbitMQ入门_11_DLX
参考资料:https://www.rabbitmq.com/dlx.html 队列中的消息可能会成为死信消息(dead lettered).让消息成为死信消息的事件有: 消息被取消确认(nack 或 ...
- Codeforces 757B - Bash's Big Day(分解因子+hashing)
757B - Bash's Big Day 思路:筛法.将所有因子个数求出,答案就是最大的因子个数,注意全为1的特殊情况. 代码: #include<bits/stdc++.h> usin ...
- jsp动作之 forward
forward说明了,就想当于php的include,require函数.(但是它是跳转.forward之前的数据都不会显示) 这么说你明白了吗.就是包含,说的好听点就是跳转,但是url地址栏却是没有 ...
- 女生学java是否真的没有优势
随着女性越来越独立,我们可以看到再以前我们认为不适合女性朋友从事的工作,也出现了越来越多的女生,例如对IT行业也不再跟之前一样畏惧.虽然当下很多人所持的观点依旧是,女生不适合IT行业,但是很多女生已经 ...