一个XML文件除了我们人去读写以外,我们希望可以通过程序去读写,利用程序去增删改查XML的过程就是XML编程
CRUD:Create、Read、Update、Delete
 
XML两种解析方式
dom解析
•将整个XML使用类似树的结构保存在内存中,再对其进行操作。
•是 W3C 组织推荐的处理 XML 的一种方式。
•需要等到XML完全加载进内存才可以进行操作
•耗费内存,当解析超大的XML时慎用。
•可以方便的对xml进行增删该查操作
sax解析:(用的多一些)(andrid 中 pull解析类似)
•逐行扫描XML文档,当遇到标签时触发解析处理器,采用事件处理的方式解析xml
• (Simple API for XML) 不是官方标准,但它是 XML 社区事实上的标准,几乎所有的 XML 解析器都支持它。
•在读取文档的同时即可对xml进行处理,不必等到文档加载结束,相对快捷
•不需要加载进内存,因此不存在占用内存的问题,可以解析超大XML
•只能用来读取XML中数据,无法进行增删改
 
 

SAX解析
SAX采用事件处理的方式解析XML文件,利用 SAX 解析 XML 文档,涉及两个部分:解析器和事件处理器。
•SAX解析器可以使用JAXP的API创建,创建出SAX解析器后,就可以指定它去解析某个xml文档。
•SAX每当解析到XML文档的一个组成部分,都会去调用事件处理器的一个方法,解析器在调用事件处理器的方法时,会把当前解析到的xml文件内容作为方法的参数传递给事件处理器。
•事件处理器由程序员编写,程序员通过事件处理器中方法的参数,就可以很轻松地得到sax解析器解析到的数据,从而可以决定如何对数据进行处理。
阅读ContentHandler API文档,常用方法:startElementendElementcharacters

SAX方式解析---步骤一
使用SAXParserFactory创建SAX解析工厂
SAXParserFactory spf = SAXParserFactory.newInstance
 
SAX方式解析---步骤二
通过SAX解析工厂得到解析器对象
SAXParser sp = spf.newSAXParser();

SAX方式解析---步骤三
通过解析器对象得到一个XML的读取器
XMLReader xmlReader = sp.getXMLReader();

SAX方式解析---步骤四
设置读取器的事件处理器
xmlReader.setContentHandler(new MyContentHandler());

SAX方式解析---步骤五
解析xml文件
xmlReader.parse("book.xml");
 
 
SAX方式解析ContentHandler
 
void setContentHandler(ContentHandler handler)
ContentHandler是一个接口,我们可以自己写一个类实现这个接口,其中提供了如下重要的方法:
 void characters(char[] ch, int start, int length)
   接收字符数据的通知。
endDocument()
接收文档的结尾的通知。
startDocument()
接收文档的开始的通知。
startElement(String uri, String localName, String qName, Attributes atts)
 接收元素开始的通知。
void endElement(String uri, String localName, String qName)
接收元素结束的通知。
 
 
SAX方式解析DefaultHandler
DefaultHandler是一个类,他默认实现了ContentHandler接口,并提供了其中所有方法的空实现,我们可以自己写一个类继承这个类,复写其中我们需要使用到的方法
 
 
package com.itheima.sax;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory; import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler; public class SaxDemo1 {
public static void main(String[] args) throws Exception {
//1.获取解析器工厂
SAXParserFactory factory = SAXParserFactory.newInstance();
//2.通过工厂获取sax解析器
SAXParser parser = factory.newSAXParser();
//3.获取读取器
XMLReader reader = parser.getXMLReader();
//4.注册事件处理器
reader.setContentHandler(new MyContentHandler2() );
//5.解析xml
reader.parse("book.xml"); }
} //适配器设计模式
class MyContentHandler2 extends DefaultHandler{
private String eleName = null;
private int count = 0;
@Override
public void startElement(String uri, String localName, String name,
Attributes attributes) throws SAXException {
this.eleName = name;
} @Override
public void characters(char[] ch, int start, int length)
throws SAXException {
if("书名".equals(eleName) && ++count==2){
System.out.println(new String(ch,start,length));
}
} @Override
public void endElement(String uri, String localName, String name)
throws SAXException {
eleName = null;
} } class MyContentHandler implements ContentHandler{ public void startDocument() throws SAXException {
System.out.println("文档解析开始了.......");
} public void startElement(String uri, String localName, String name,
Attributes atts) throws SAXException {
System.out.println("发现了开始标签,"+name);
} public void characters(char[] ch, int start, int length)
throws SAXException {
System.out.println(new String(ch,start,length));
} public void endElement(String uri, String localName, String name)
throws SAXException {
System.out.println("发现结束标签,"+name);
} public void endDocument() throws SAXException {
System.out.println("文档解析结束了.......");
} public void endPrefixMapping(String prefix) throws SAXException {
// TODO Auto-generated method stub } public void ignorableWhitespace(char[] ch, int start, int length)
throws SAXException {
// TODO Auto-generated method stub } public void processingInstruction(String target, String data)
throws SAXException {
// TODO Auto-generated method stub } public void setDocumentLocator(Locator locator) {
// TODO Auto-generated method stub } public void skippedEntity(String name) throws SAXException {
// TODO Auto-generated method stub } public void startPrefixMapping(String prefix, String uri)
throws SAXException {
// TODO Auto-generated method stub } }

  

DOM4J解析
DOM4J解析XML文档
 
Dom4j是一个简单、灵活的开放源代码的库。Dom4j是由早期开发JDOM的人分离出来而后独立开发的。与JDOM不同的是,dom4j使用接口和抽象基类,虽然Dom4j的API相对要复杂一些,但它提供了比JDOM更好的灵活性。
Dom4j是一个非常优秀的Java XML API,具有性能优异、功能强大和极易使 用的特点。现在很多软件采用的Dom4j,例如Hibernate,包括sun公司自己的JAXM也用了Dom4j。
使用Dom4j开发,需下载dom4j相应的jar文件。
 
创建解析器:
SAXReader reader = new SAXReader();
利用解析器读入xml文档:
Document   document = reader.read(new File("input.xml"));
获取文档的根节点:
 Element root = document.getRootElement();
 
1.取得某个节点的子节点.
Element element =ele.element(“书名");
List elementList =ele.elements(“书名");
List elementList =ele.elements();
 
2.获取节点的名字
node.getName();
 
3.设置节点的名字
node.setName(String newName);
 
4.取得节点的文字(标签体)
String text=node.getText()
5.设置节点的文字(标签体)
node.setText("aaa");
 
6.添加子节点.
ele.add(Element e);
ele.addElement("age");
 
7.删除子节点节点.
parentElm.remove(childElm);
 
8获取节点类型
node.getNodeType() ;
 
9.获取父节点
node.getParent();

10.取得某节点对象的某属性
Attribute attr= ele.attribute("aaa");
Attribute attr= ele.attribute(0);
List list = ele.attributes();
String value = ele.attributeValue("aaa");
Iterator it = ele.attributeIterator();
 
11.设置某节点的属性
ele.add(Attribute attr);
ele.addAttribute(name, value);
ele.setAttributes(List attrs);
 
12.删除某属性
 ele.remove(attribute);
13.在指定位置插入节点
•1.得到插入位置的节点列表(list)
•2.调用list.add(index,elemnent),由index决定element的插入位置。
•Element元素可以通过DocumentHelper对象得到。示例代码:
 
Element aaa = DocumentHelper.createElement("aaa");
aaa.setText("aaa");
 
List list = root.element("").elements();
list.add(1, aaa);
 

DOM4j属性
1.取得属性的名、值
String name = attribute.getName();
String value = attribute.getValue();
 
2.设置某属性的名、值
attribute.setName();
attribute.setValue();
 
DOM4j字符串和XML的转换
1.将字符串转化为XML
 
     String text = "<members> <member>sitinspring</member></members>";
Document document = DocumentHelper.parseText(text);
 
2.将文档或节点的XML转化为字符串.

String xmlStr = node.asXML();
 
DOM4j将文档写入XML文件
方式一:
调用Node提供的write(Writer writer) 方法,使用默认方式将节点输出到流中:
node.write(new FileWriter("book.xml"));
•乱码问题:Dom4j在将文档载入内存时使用的是文档声明中encoding属性声明的编码集进行编码,如果在此时使用的writer的内部编码集与最初载入内存时使用的编码集不同则会出现乱码问题。
•FileWriter默认使用操作系统本地码表即gb2312编码,并且无法更改。
•此时可以使用OutputStreamWriter(FileOutputStream("filePath"),"utf-8");的方式自己封装一个指定码表的Writer使用,从而解决乱码问题。
 
l方式二:
利用XMLWriter写出Node:
  XMLWriter writer = new XMLWriter(new  FileWriter("output.xml"));
  writer.write(node);
  writer.close();
•注意:使用这种方式输出时,XMLWriter首先会将内存中的docuemnt翻译成UTF-8格式的document,在进行输出,这时有可能出现乱码问题。
•可以使用OutputFormat 指定XMLWriter转换的编码为其他编码。
OutputFormat format = OutputFormat.createPrettyPrint();            
     format.setEncoding("GBK");       
XMLWriter writer =
new XMLWriter(newFileWriter("output.xml"),format);
•Writer使用的编码集与文档载入内存时使用的编码集不同导致乱码,使用字节流或自己封装指定编码的字符流即可。参照上文
 
 
 
 
 

你所应该知道的Dom4J

创建解析器:

SAXReader reader = new SAXReader();

利用解析器读入xml文档:
Document   document = reader.read(new File("input.xml"));

获取文档的根节点:

Element root = document.getRootElement();

接口继承结构:

Node  ---

Branch

--Document

--Element

----

Attribute

Node接口

String

asXML()
asXMLreturns the textual XML representation of this node.

将一个节点转换为字符串

String

getName()
getNamereturns the name of this node.

获取节点的名称,如果是元素则获取到元素名,如果是属性获取到属性名

short

getNodeType()
Returns the code according to the type of node.

获取节点类型,在Node接口上定义了一些静态short类型的常量用来表示各种类型

Element

getParent()
getParentreturns the parent Element if this node supports the parent relationship or null if it is the root element or does not support the parent relationship.

获取父节点,如果是根元素调用则返回null,如果是其他元素调用则返回父元素,如果是属性调用则返回属性所依附的元素。

String

getText()
Returns the text of this node.

返回节点文本,如果是元素则返回标签体,如果是属性则返回属性值

List

selectNodes(String xpathExpression)
selectNodesevaluates an XPath expression and returns the result as a List of Node instances or String instances depending on the XPath expression.

利用xpath表达式,选择节点

void

setName(String name)
Sets the text data of this node or this method will throw an UnsupportedOperationException if it is read-only.

设置节点的名称,元素可以更改名称,属性则不可以,会抛出UnsupportedOperationException 异常

void

setText(String text)
Sets the text data of this node or this method will throw an UnsupportedOperationException if it is read-only.

设置节点内容,如果是元素则设置标签体,如果是属性则设置属性的值

void

write(Writer writer)
writewrites this node as the default XML notation for this node.

将节点写出到一个输出流中,元素、属性均支持

Branch接口(实现了Node接口)

void

add(Element element)
Adds the given Element to this branch.

增加一个子节点

Element

addElement(QName qname)
Adds a new Element node with the given QNameto this branch and returns a reference to the new node.

增加一个给定名字的子节点,并且返回这个新创建的节点的引用

int

indexOf(Node node)
Returns the index of the given node if it is a child node of this branch or -1 if the given node is not a child node.

获取给定节点在所有直接点中的位置号,如果该节点不是此分支的子节点,则返回-1

boolean

remove(Element element)
Removes the given Element if the node is an immediate child of this branch.

删除给定子元素,返回布尔值表明是否删除成功。

Element接口(实现了BranchNode接口)

void

add(Attribute attribute)
Adds the given Attribute to this element.

增加一个属性

Element

addAttribute(QName qName, String value)
Adds the attribute value of the given fully qualified name.

为元素增加属性,用给定的属性名和属性值,并返回该元素

Element

addAttribute(String name, String value)
           Adds the attribute value of the given local name.

为元素增加属性

Attribute

attribute(int index)
Returns the attribute at the specified indexGets the

获取指定位置的属性

Attribute

attribute(QName qName)
DOCUMENT ME!

获取指定名称的属性

Iterator

attributeIterator()
DOCUMENT ME!

获取属性迭代器

List

attributes()
Returns the Attributeinstances this element contains as a backed Listso that the attributes may be modified directly using the Listinterface.

获取该元素的所有属性,以一个list返回

String

attributeValue(QName qName)
This returns the attribute value for the attribute with the given fully qualified name or null if there is no such attribute or the empty string if the attribute value is empty.

获取指定名称属性的值,如果不存在该属性返回null,如果存在该属性但是属性值为空,则返回空字符串

Element

element(QName qName)
Returns the first element for the given fully qualified name.

获取指定名称的子元素,如果有多个该名称的子元素,则返回第一个

Element

element(String name)
Returns the first element for the given fully qualified name.

获取指定名称的子元素,如果有多个该名称的子元素,则返回第一个

Iterator

elementIterator()
Returns an iterator over all this elements child elements.

获取子元素迭代器

Iterator

elementIterator(QName qName)
Returns an iterator over the elements contained in this element which match the given fully qualified name.

获取指定名称的子元素的迭代器

List

elements()
Returns the elements contained in this element.

获取所有子元素,并用一个list返回

List

elements(QName qName)
Returns the elements contained in this element with the given fully qualified name.

获取所有指定名称的子元素,并用一个list返回

String

getText()
Returns the text value of this element without recursing through child elements.

获取元素标签体

boolean

remove(Attribute attribute)
Removes the given Attribute from this element.

移除元素上的属性

void

setAttributes(List attributes)
Sets the attributes that this element contains

将list中的所有属性设置到该元素上

Attribute接口(实现了Node接口)

QName

getQName()
Returns the QName of this attribute which represents the local name, the qualified name and the Namespace.

获取属性名称

String

getValue()
Returns the value of the attribute.

获取属性的值

void

setValue(String value)
Sets the value of this attribute or this method will throw an UnsupportedOperationException if it is read-only.

设置属性的值

DocumentHelper 类

static Attribute

createAttribute(Element owner, QName qname, String value)

创建一个Attribute

static Document

createDocument()

创建一个Document

static Document

createDocument(Element rootElement)

以给定元素作为根元素创建Document

static Element

createElement(QName qname)

以给定名称创建一个Element

static Document

parseText(String text)
parseTextparses the given text as an XML document and returns the newly created Document.

将一段字符串转化为Document

将节点写出到XML文件中去

方法1:

调用Node提供的write(Writer writer) 方法,使用默认方式将节点输出到流中:

node.write(new FileWriter("book.xml"));

乱码问题:

Dom4j在将文档载入内存时使用的是文档声明中encoding属性声明的编码集进行编码, 如果在此时使用writer输出时writer使用的内部编码集与encoding不同则会有乱码问题。

FileWriter默认使用操作系统本地码表即gb2312编码,并且无法更改。

此时可以使用OutputStreamWriter(FileOutputStream("filePath"),"utf-8");的方式自己封装 一个指定码表的Writer使用,从而解决乱码问题。

方式2:

利用XMLWriter写出Node:
   XMLWriter writer = new XMLWriter(new  FileWriter("output.xml"));
   writer.write(node);
  writer.close();

乱码问题:

(1)使用这种方式输出时,XMLWriter首先会将内存中的docuemnt翻译成UTF-8 格式的document,在进行输出,这时有可能出现乱码问题。

可以使用OutputFormat 指定XMLWriter转换的编码为其他编码。

OutputFormat format = OutputFormat.createPrettyPrint();

format.setEncoding("GBK");       
XMLWriter writer = new XMLWriter(new FileWriter("output.xml"),format);

(2)Writer使用的编码集与文档载入内存时使用的编码集不同导致乱码,使用字节流 或自己封装指定编码的字符流即可(参照方法1)。

package com.itheima.dom4j;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader; public class Dom4jDemo1 {
public static void main(String[] args) throws Exception {
//1.获取解析器
SAXReader reader = new SAXReader();
//2.解析xml获取代表整个文档的dom对象
Document dom = reader.read("book.xml");
//3.获取根节点
Element root = dom.getRootElement();
//4.获取书名进行打印
String bookName = root.element("书").element("书名").getText();
System.out.println(bookName);
}
}

  

package com.itheima.dom4j;

import java.io.FileOutputStream;
import java.util.List; import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import org.junit.Test; public class Demo4jDemo2 {
@Test
public void attr() throws Exception{
SAXReader reader = new SAXReader();
Document dom = reader.read("book.xml");
Element root = dom.getRootElement(); Element bookEle = root.element("书");
//bookEle.addAttribute("出版社", "传智出版社");
// String str = bookEle.attributeValue("出版社");
// System.out.println(str);
Attribute attr = bookEle.attribute("出版社");
attr.getParent().remove(attr); XMLWriter writer = new XMLWriter(new FileOutputStream("book.xml"),OutputFormat.createPrettyPrint());
writer.write(dom);
writer.close();
} @Test
public void del() throws Exception{
SAXReader reader = new SAXReader();
Document dom = reader.read("book.xml");
Element root = dom.getRootElement(); Element price2Ele = root.element("书").element("特价");
price2Ele.getParent().remove(price2Ele); XMLWriter writer = new XMLWriter(new FileOutputStream("book.xml"),OutputFormat.createPrettyPrint());
writer.write(dom);
writer.close();
} @Test
public void update()throws Exception{
SAXReader reader = new SAXReader();
Document dom = reader.read("book.xml");
Element root = dom.getRootElement(); root.element("书").element("特价").setText("4.0元"); XMLWriter writer = new XMLWriter(new FileOutputStream("book.xml"),OutputFormat.createPrettyPrint());
writer.write(dom);
writer.close();
} @Test
public void add()throws Exception{
SAXReader reader = new SAXReader();
Document dom = reader.read("book.xml");
Element root = dom.getRootElement();
//凭空创建<特价>节点,设置标签体
Element price2Ele = DocumentHelper.createElement("特价");
price2Ele.setText("40.0元");
//获取父标签<书>将特价节点挂载上去
Element bookEle = root.element("书");
bookEle.add(price2Ele); //将内存中的dom树会写到xml文件中,从而使xml中的数据进行更新
// FileWriter writer = new FileWriter("book.xml");
// dom.write(writer);
// writer.flush();
// writer.close();
XMLWriter writer = new XMLWriter(new FileOutputStream("book.xml"),OutputFormat.createPrettyPrint());
writer.write(dom);
writer.close();
} @Test
public void find() throws Exception{
SAXReader reader = new SAXReader();
Document dom = reader.read("book.xml");
Element root = dom.getRootElement(); List<Element> list = root.elements();
Element book2Ele = list.get(1);
System.out.println(book2Ele.element("书名").getText()); }
}

  

 
 
 
 
 
 
 

javaweb入门20160305---xml的解析入门的更多相关文章

  1. JavaWeb学习日记----XML的解析

    XML的解析简介: 在学习JavaScript时,我们用的DOM来解析HEML文档,根据HTML的层级结构在内存中分配一个树形结构,把HTML的标签啊,属性啊和文本之类的都封装成对象. 比如:docu ...

  2. Javaweb入门20160301 ---xml入门

    一.xml语法 1.文档声明 用来声明xml的基本属性,用来指挥解析引擎如何去解析当前xml 通常一个xml都要包含并且只能包含一个文档声明 xml的文档必须在整个xml的最前面,在文档声明之前不能有 ...

  3. OkHttp框架从入门到放弃,解析图片使用Picasso裁剪,二次封装OkHttpUtils,Post提交表单数据

    OkHttp框架从入门到放弃,解析图片使用Picasso裁剪,二次封装OkHttpUtils,Post提交表单数据 我们这片博文就来聊聊这个反响很不错的OkHttp了,标题是我恶搞的,本篇将着重详细的 ...

  4. 【网络爬虫入门03】爬虫解析利器beautifulSoup模块的基本应用

    [网络爬虫入门03]爬虫解析利器beautifulSoup模块的基本应用   1.引言 网络爬虫最终的目的就是过滤选取网络信息,因此最重要的就是解析器了,其性能的优劣直接决定这网络爬虫的速度和效率.B ...

  5. SpringBoot快速入门(解析+入门案例源码实现)

    这里写目录标题 SpringBoot入门 一.SpringBoot 概念 二.JavaConfig 入门 1. JavaConfig 概念 2. 项目准备 三.常用注解 四.SpringBoot 入门 ...

  6. JavaWeb学习笔记——XML解析

    DOM解析操作 只在跟节点<addresslist>下面建立一个子节点<name> <?xml version="1.0" encoding=&quo ...

  7. Linux入门:运行级别解析

    Linux入门:运行级别解析   一.查看当前运行级别 Ubuntu中,runlevel命令 可以查看当前运行级别: CentOS中,who -r 命令查看当前运行级别:   www.2cto.com ...

  8. Maven入门2-pom.xml文件与settings.xml文件

    Maven入门2-pom.xml文件与settings.xml文件 本文内容来源于官网文档部分章节,settings.xml文件:参考http://maven.apache.org/settings. ...

  9. Spring 入门 web.xml配置详解

    Spring 入门 web.xml配置详解 https://www.cnblogs.com/cczz_11/p/4363314.html https://blog.csdn.net/hellolove ...

  10. 用java实现一个简易编译器1-词法解析入门

    本文对应代码下载地址为: http://download.csdn.net/detail/tyler_download/9435103 视频地址: http://v.youku.com/v_show/ ...

随机推荐

  1. 从头开始编写一个Orchard网上商店模块(3) - 创建Orchard.Webshop模块项目

    原文地址:http://skywalkersoftwaredevelopment.net/blog/writing-an-orchard-webshop-module-from-scratch-par ...

  2. HDU4370 0 or 1 最短路

    分析: 1001  (已更新) 显然,题目给的是一个0/1规划模型.解题的关键在于如何看出这个模型的本质.3个条件明显在刻画未知数之间的关系,从图论的角度思考问题,容易得到下面3个结论:1.X12+X ...

  3. xcodebuild导出ipa方法

    xcode 5.x版本导出ipa是不需要开发者账号,而xcode6以后导出ipa必须要求选择开发者team,无法绕开,但我们使用xcodebuild命令行可以无视这个限制 环境: mac osx 10 ...

  4. 【CSS】Intermediate7:Pseudo Elements

    1.selector:pseudo element{property:value;} 2.first-letter  first-line CSS3:: 与pseudo class 区别 old br ...

  5. 最新版springside4基于Quickstart项目,创建自己的项目

    直接输入 mvn archetype:generate -DarchetypeGroupId=org.springside.examples -DarchetypeArtifactId=quickst ...

  6. Android--应用开发1(应用程序框架)

    应用程序的框架,就是所有开发者共同是有和遵循的约定,大家在约定上进行必要的扩展,但程序的主体结构是一致的. Android系统提供给开发者一个框架,我们所有的应用开发就是在这个框架上进行扩展,下来看看 ...

  7. A list of base boxes for Vagrant - Vagrantbox.es

    Create image server with nginx + lua (Openresty) + graphicsmagick (Part I) | Ian's PhotograPhy Blog ...

  8. hdoj 3849 By Recognizing These Guys, We Find Social Networks Useful【双连通分量求桥&&输出桥&&字符串处理】

    By Recognizing These Guys, We Find Social Networks Useful Time Limit: 2000/1000 MS (Java/Others)     ...

  9. 使用ProcDump在程序没有响应时自动收集dump

    博客搬到了fresky.github.io - Dawei XU,请各位看官挪步.最新的一篇是:使用ProcDump在程序没有响应时自动收集dump.

  10. hdu 1039 Easier Done Than Said? 字符串

    Easier Done Than Said?                                                                     Time Limi ...