XML解析技术概述
- XML解析方式分为两种:dom和sax
- dom:(Document Object Model, 即文档对象模型) 是 W3C 组织推荐的处理 XML 的一种方式。
- sax: (Simple API for XML) 不是官方标准,但它是 XML 社区事实上的标准,几乎所有的 XML 解析器都支持它。
- XML解析器
Crimson、Xerces 、Aelfred2
- XML解析开发包
Jaxp、Jdom、dom4j
JAXP
- JAXP 开发包是J2SE的一部分,它由javax.xml、org.w3c.dom 、org.xml.sax 包及其子包组成
- 在 javax.xml.parsers 包中,定义了几个工厂类,程序员调用这些工厂类,可以得到对xml文档进行解析的 DOM 或 SAX
的解析器对象。
使用JAXP进行DOM解析
javax.xml.parsers包中的DocumentBuilderFactory用于创建DOM模式的解析器对象 ,DocumentBuilderFactory是一个抽象工厂类,它不能直接实例化,但该类提供了一个newInstance方法 ,这个方法会根据本地平台默认安装的解析器,自动创建一个工厂的对象并返回。
获得JAXP中的DOM解析器
- 调用
DocumentBuilderFactory.newInstance()方法得到创建 DOM 解析器的工厂。 - 调用工厂对象的
newDocumentBuilder方法得到 DOM 解析器对象。 - 调用 DOM 解析器对象的
parse()方法解析 XML 文档,得到代表整个文档的 Document
对象,进行可以利用DOM特性对整个XML文档进行操作了。
DOM编程
- DOM模型(document object model)
- DOM解析器在解析XML文档时,会把文档中的所有元素,按照其出现的层次关系,解析成一个个Node对象(节点)。
- 在dom中,节点之间关系如下:
- 位于一个节点之上的节点是该节点的父节点(parent)
- 一个节点之下的节点是该节点的子节点(children)
- 同一层次,具有相同父节点的节点是兄弟节点(sibling)
- 一个节点的下一个层次的节点集合是节点后代(descendant)
- 父、祖父节点及所有位于节点上面的,都是节点的祖先(ancestor)
Node对象
- Node对象提供了一系列常量来代表结点的类型,当开发人员获得某个Node类型后,就可以把Node节点转换成相应的节点对象(Node的子类对象),以便于调用其特有的方法。(查看API文档)
- Node对象提供了相应的方法去获得它的父结点或子结点。编程人员通过这些方法就可以读取整个XML文档的内容、或添加、修改、删除XML文档的内容了。
DOM方式解析XML文件
- DOM解析编程
- 遍历所有节点
- 查找某一个节点
- 删除结点
- 更新结点
- 添加节点
DOM编程练习
book1.xml
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<书架>
<书 name="yyyyyyy">
<售价>109</售价>
<售价>39元</售价>
<书名>Java就业培训教程</书名>
<作者>张孝祥</作者>
</书>
<书>
<书名>JavaScript网页开发</书名>
<作者>张孝祥</作者>
<售价>28.00元</售价>
</书>
</书架>
- 遍历所有节点
public class Demo1 {
/**使用jaxp操作xml文档
* @param args
* @throws ParserConfigurationException
* @throws IOException
* @throws SAXException
*/
public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
//1.获取工厂
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
//2.产生解析器
DocumentBuilder builder = factory.newDocumentBuilder();
//3.解析xml文档,得到代表文档的document
Document document = builder.parse(new File("src/book1.xml"));
//遍历
list(document);
}
//遍历
public static void list(Node node){
if(node.getNodeType()==Node.ELEMENT_NODE){
System.out.println(node.getNodeName());
}
NodeList list = node.getChildNodes();
for(int i=0;i<list.getLength();i++){
Node child = list.item(i);
list(child);
}
}
}
- 查找某一个节点
//得到售价结点的值
@Test
public void read() throws Exception{
//1.获取工厂
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(new File("src/book.xml"));
NodeList list = document.getElementsByTagName("售价");
Node price = list.item(0);
String value = price.getTextContent();
System.out.println(value);
}
- 添加节点
//向指定节点中增加孩子节点(售价节点)
@Test
public void add() throws Exception{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(new File("src/book1.xml"));
//创建需要增加的节点
Node price = document.createElement("售价");
price.setTextContent("59元");
//得到需要增加的节点的父亲
Node parent = document.getElementsByTagName("书").item(0);
//把需要增加的节点挂到父结点上
parent.appendChild(price);
//把内存中的document写到xml文档
TransformerFactory tf = TransformerFactory.newInstance();
//得到转换器
Transformer ts = tf.newTransformer();
ts.transform(new DOMSource(document), new StreamResult(new File("src/book1.xml")));
}
执行后
<?xml version="1.0" encoding="utf-8" standalone="no"?><书架>
<书 name="yyyyyyy">
<售价>109</售价>
<售价>39元</售价>
<书名>Java就业培训教程</书名>
<作者>张孝祥</作者>
<售价>59元</售价></书>
<书>
<书名>JavaScript网页开发</书名>
<作者>张孝祥</作者>
<售价>28.00元</售价>
</书>
</书架>
//向指定位置上插入售价节点
@Test
public void add2() throws Exception{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(new File("src/book1.xml"));
Node node = document.createElement("售价");
node.setTextContent("39元");
Node parent = document.getElementsByTagName("书").item(0);
parent.insertBefore(node, document.getElementsByTagName("书名").item(0));
TransformerFactory tf = TransformerFactory.newInstance();
Transformer ts = tf.newTransformer();
ts.transform(new DOMSource(document), new StreamResult(new File("src/book1.xml")));
}
执行后
<?xml version="1.0" encoding="utf-8" standalone="no"?><书架>
<书 name="yyyyyyy">
<售价>109</售价>
<售价>39元</售价>
<售价>39元</售价><书名>Java就业培训教程</书名>
<作者>张孝祥</作者>
<售价>59元</售价></书>
<书>
<书名>JavaScript网页开发</书名>
<作者>张孝祥</作者>
<售价>28.00元</售价>
</书>
</书架>
- 更新结点
//修改结点的值:<售价>109</售价>改为111
@Test
public void update() throws Exception{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(new File("src/book1.xml"));
Node price = document.getElementsByTagName("售价").item(0);
price.setTextContent("111");
//把内存中的document写到xml文档
TransformerFactory tf = TransformerFactory.newInstance();
//得到转换器
Transformer ts = tf.newTransformer();
ts.transform(new DOMSource(document), new StreamResult(new File("src/book1.xml")));
}
执行后
<?xml version="1.0" encoding="utf-8" standalone="no"?><书架>
<书 name="yyyyyyy">
<售价>111</售价>
<售价>39元</售价>
<售价>39元</售价><书名>Java就业培训教程</书名>
<作者>张孝祥</作者>
<售价>59元</售价></书>
<书>
<书名>JavaScript网页开发</书名>
<作者>张孝祥</作者>
<售价>28.00元</售价>
</书>
</书架>
- 删除结点
//删除xml文档的售价结点
@Test
public void delete() throws Exception{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(new File("src/book1.xml"));
Node node = document.getElementsByTagName("售价").item(2);
node.getParentNode().removeChild(node);
TransformerFactory tf = TransformerFactory.newInstance();
Transformer ts = tf.newTransformer();
ts.transform(new DOMSource(document), new StreamResult(new File("src/book1.xml")));
}
执行后
<?xml version="1.0" encoding="utf-8" standalone="no"?><书架>
<书 name="yyyyyyy">
<售价>111</售价>
<售价>39元</售价>
<书名>Java就业培训教程</书名>
<作者>张孝祥</作者>
<售价>59元</售价></书>
<书>
<书名>JavaScript网页开发</书名>
<作者>张孝祥</作者>
<售价>28.00元</售价>
</书>
</书架>
- 操作xml文档属性
//操作xml文档属性
@Test
public void updateAttribute() throws Exception{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(new File("src/book1.xml"));
//操作xml文档的元素时,一般都把元素当作node对象,但是程序员如果发现node不好使时,就应把node强转成相应类型
Node node = document.getElementsByTagName("书").item(0);
Element book = null;
if(node.getNodeType()==Node.ELEMENT_NODE){ //在作结点转换之前,最好先判断结点类型
book = (Element)node;
}
book.setAttribute("name", "yyyyyyy");
book.setAttribute("password", "123");
TransformerFactory tf = TransformerFactory.newInstance();
Transformer ts = tf.newTransformer();
ts.transform(new DOMSource(document), new StreamResult(new File("src/book1.xml")));
}
执行后
<?xml version="1.0" encoding="utf-8" standalone="no"?><书架>
<书 name="yyyyyyy" password="123">
<售价>111</售价>
<售价>39元</售价>
<售价>39元</售价><书名>Java就业培训教程</书名>
<作者>张孝祥</作者>
<售价>59元</售价></书>
<书>
<书名>JavaScript网页开发</书名>
<作者>张孝祥</作者>
<售价>28.00元</售价>
</书>
</书架>
//移除xml文档属性
@Test
public void updateAttribute() throws Exception{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(new File("src/book1.xml"));
//操作xml文档的元素时,一般都把元素当作node对象,但是程序员如果发现node不好使时,就应把node强转成相应类型
Node node = document.getElementsByTagName("书").item(0);
Element book = null;
if(node.getNodeType()==Node.ELEMENT_NODE){ //在作结点转换之前,最好先判断结点类型
book = (Element)node;
}
// book.setAttribute("name", "yyyyyyy");
// book.setAttribute("password", "123");
book.removeAttribute("password");
TransformerFactory tf = TransformerFactory.newInstance();
Transformer ts = tf.newTransformer();
ts.transform(new DOMSource(document), new StreamResult(new File("src/book1.xml")));
}
执行后
<?xml version="1.0" encoding="utf-8" standalone="no"?><书架>
<书 name="yyyyyyy">
<售价>111</售价>
<售价>39元</售价>
<售价>39元</售价><书名>Java就业培训教程</书名>
<作者>张孝祥</作者>
<售价>59元</售价></书>
<书>
<书名>JavaScript网页开发</书名>
<作者>张孝祥</作者>
<售价>28.00元</售价>
</书>
</书架>
- 删除整个XML文档
//删除整个xml文档
@Test
public void delete2() throws Exception{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(new File("src/book1.xml"));
//得到要删除的结点
Element e = (Element) document.getElementsByTagName("售价").item(0);
e.getParentNode().getParentNode().getParentNode().removeChild(e.getParentNode().getParentNode());
TransformerFactory tf = TransformerFactory.newInstance();
Transformer ts = tf.newTransformer();
ts.transform(new DOMSource(document), new StreamResult(new File("src/book1.xml")));
}
执行后
<?xml version="1.0" encoding="utf-8" standalone="no"?>
更新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获得。
SAX解析
- 在使用 DOM 解析 XML 文档时,需要读取整个 XML 文档,在内存中构架代表整个 DOM
树的Doucment对象,从而再对XML文档进行操作。此种情况下,如果 XML
文档特别大,就会消耗计算机的大量内存,并且容易导致内存溢出。 - SAX解析允许在读取文档的时候,即对文档进行处理,而不必等到整个文档装载完才会文档进行操作。
- SAX采用事件处理的方式解析XML文件,利用 SAX 解析 XML 文档,涉及两个部分:解析器和事件处理器:
- 解析器可以使用JAXP的API创建,创建出SAX解析器后,就可以指定解析器去解析某个XML文档。
- 解析器采用SAX方式在解析某个XML文档时,它只要解析到XML文档的一个组成部分,都会去调用事件处理器的一个方法,解析器在调用事件处理器的方法时,会把当前解析到的xml文件内容作为方法的参数传递给事件处理器。
- 事件处理器由程序员编写,程序员通过事件处理器中方法的参数,就可以很轻松地得到sax解析器解析到的数据,从而可以决定如何对数据进行处理。
- 阅读ContentHandler API文档,常用方法:startElement、endElement、characters
SAX方式解析XML文档
- 使用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");
SAX解析编程
book.xml
<?xml version="1.0" encoding="UTF-8"?>
<书架>
<书 name="yyyyyyy">
<售价>209元</售价>
<售价>19元</售价>
<书名>Java就业培训教程</书名>
<作者>张孝祥</作者>
<售价>19元</售价>
<售价>19元</售价>
</书>
<书>
<书名>JavaScript网页开发</书名>
<作者>张孝祥</作者>
<售价>28.00元</售价>
</书>
</书架>
public class Demo1 {
/**
*sax方式解析book1.xml文件
* @throws SAXException
* @throws ParserConfigurationException
* @throws IOException
*/
public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
//1.创建工厂
SAXParserFactory factory = SAXParserFactory.newInstance();
//2.用工厂创建解析器
SAXParser sp = factory.newSAXParser();
//3.利用解析器得到reader
XMLReader reader = sp.getXMLReader();
//4、在解析xml文档之前,设置好事件处理器
reader.setContentHandler(new MyContentHandler());
//4.利用reader读取 xml文档
reader.parse("src/book1.xml");
}
}
//得到xml文档内容的事件处理器
class MyContentHandler implements ContentHandler{
public void startElement(String uri, String localName, String name,
Attributes atts) throws SAXException {
System.out.println("当前解析到了:" + name + ",这个标签是开始标签");
for(int i=0;i<atts.getLength();i++){
String attname = atts.getQName(i);
String attvalue = atts.getValue(i);
System.out.println(attname + "=" + attvalue);
}
}
public void endElement(String uri, String localName, String name)
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 endDocument() throws SAXException {
// TODO Auto-generated method stub
}
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 startDocument() throws SAXException {
// TODO Auto-generated method stub
}
public void startPrefixMapping(String prefix, String uri)
throws SAXException {
// TODO Auto-generated method stub
}
}
运行结果:
当前解析到了:书架,这个标签是开始标签
当前解析到了内容:
当前解析到了:书,这个标签是开始标签
name=yyyyyyy
当前解析到了内容:
当前解析到了:售价,这个标签是开始标签
当前解析到了内容:209元
当前解析到了:售价,这个标签是结束标签
当前解析到了内容:
当前解析到了:售价,这个标签是开始标签
当前解析到了内容:19元
当前解析到了:售价,这个标签是结束标签
当前解析到了内容:
当前解析到了:书名,这个标签是开始标签
当前解析到了内容:Java就业培训教程
当前解析到了:书名,这个标签是结束标签
当前解析到了内容:
当前解析到了:作者,这个标签是开始标签
当前解析到了内容:张孝祥
当前解析到了:作者,这个标签是结束标签
当前解析到了内容:
当前解析到了:售价,这个标签是开始标签
当前解析到了内容:19元
当前解析到了:售价,这个标签是结束标签
当前解析到了内容:
当前解析到了:售价,这个标签是开始标签
当前解析到了内容:19元
当前解析到了:售价,这个标签是结束标签
当前解析到了内容:
当前解析到了:书,这个标签是结束标签
当前解析到了内容:
当前解析到了:书,这个标签是开始标签
当前解析到了内容:
当前解析到了:书名,这个标签是开始标签
当前解析到了内容:JavaScript网页开发
当前解析到了:书名,这个标签是结束标签
当前解析到了内容:
当前解析到了:作者,这个标签是开始标签
当前解析到了内容:张孝祥
当前解析到了:作者,这个标签是结束标签
当前解析到了内容:
当前解析到了:售价,这个标签是开始标签
当前解析到了内容:28.00元
当前解析到了:售价,这个标签是结束标签
当前解析到了内容:
当前解析到了:书,这个标签是结束标签
当前解析到了内容:
当前解析到了:书架,这个标签是结束标签
public class Demo1 {
/**
*sax方式解析book1.xml文件
* @throws SAXException
* @throws ParserConfigurationException
* @throws IOException
*/
public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
//1.创建工厂
SAXParserFactory factory = SAXParserFactory.newInstance();
//2.用工厂创建解析器
SAXParser sp = factory.newSAXParser();
//3.利用解析器得到reader
XMLReader reader = sp.getXMLReader();
//4、在解析xml文档之前,设置好事件处理器
reader.setContentHandler(new MyContentHandler2());
//4.利用reader读取 xml文档
reader.parse("src/book1.xml");
}
}
//用于获取第一个售价节点的值:<售价>109</售价>
class MyContentHandler2 extends DefaultHandler{
private boolean isOk = false;
private int index = 1;
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
if(isOk==true && index==1){
System.out.println(new String(ch,start,length));
}
}
@Override
public void startElement(String uri, String localName, String name,
Attributes attributes) throws SAXException {
if(name.equals("售价")){
isOk = true;
}
}
@Override
public void endElement(String uri, String localName, String name)
throws SAXException {
if(name.equals("售价")){
isOk = false;
index++;
}
}
}
修改book.xml
<?xml version="1.0" encoding="UTF-8"?>
<书架>
<书 name="yyyyyyy">
<售价>209元</售价>
<售价>19元</售价>
<书名>Java就业培训教程</书名>
<作者>张孝祥</作者>
<售价>19元</售价>
<售价>19元</售价>
</书>
<书>
<书名>JavaScript网页开发</书名>
<作者>黎活明</作者>
<售价>28.00元</售价>
</书>
</书架>
public class Demo1 {
/**
*sax方式解析book1.xml文件
* @throws SAXException
* @throws ParserConfigurationException
* @throws IOException
*/
public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
//1.创建工厂
SAXParserFactory factory = SAXParserFactory.newInstance();
//2.用工厂创建解析器
SAXParser sp = factory.newSAXParser();
//3.利用解析器得到reader
XMLReader reader = sp.getXMLReader();
//4、在解析xml文档之前,设置好事件处理器
reader.setContentHandler(new TagValueHandler());
//4.利用reader读取 xml文档
reader.parse("src/book1.xml");
}
}
//获取指定标签的值
class TagValueHandler extends DefaultHandler{
private String currentTag; //记住当前生命标签
private int needNumber = 2; //记住想要获取第几个标签
private int currentNumber; //当前解析到的是第几个标签
@Override
public void startElement(String uri, String localName, String name,
Attributes attributes) throws SAXException {
currentTag = name;
if(currentTag.equals("作者")){
currentNumber ++;
}
}
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
if("作者".equals(currentTag) && currentNumber == needNumber){
System.out.println(new String(ch,start,length));
}
}
@Override
public void endElement(String uri, String localName, String name)
throws SAXException {
currentTag = null;
}
}
sax解析案例(javabean封装xml文档数据)
<?xml version="1.0" encoding="UTF-8"?>
<书架>
<书 name="yyyyyyy">
<书名>Java就业培训教程</书名>
<作者>张孝祥</作者>
<售价>19元</售价>
</书>
<书>
<书名>JavaScript网页开发</书名>
<作者>黎活明</作者>
<售价>28.00元</售价>
</书>
</书架>
创建一个book类
public class Book {
private String name;
private String author;
private String price;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
@Override
public String toString() {
return "Book [name=" + name + ", author=" + author + ", price=" + price + "]";
}
}
public class Demo2 {
/**
*sax方式解析book1.xml文件
* @throws SAXException
* @throws ParserConfigurationException
* @throws IOException
*/
public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
//1.创建工厂
SAXParserFactory factory = SAXParserFactory.newInstance();
//2.用工厂创建解析器
SAXParser sp = factory.newSAXParser();
//3.利用解析器得到reader
XMLReader reader = sp.getXMLReader();
//4、在解析xml文档之前,设置好事件处理器
BeanListHandler handler = new BeanListHandler();
reader.setContentHandler(handler);
//4.利用reader读取 xml文档
reader.parse("src/book1.xml");
List<Book> list = handler.getList();
for(Book book : list){
System.out.println(book);
}
}
}
//把xml文档中的每一本书封装到一个book对象,并把对个book对象放在一个list集合中返回
class BeanListHandler extends DefaultHandler{
private List list = new ArrayList();
private String currentTag;
private Book book;
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
// TODO Auto-generated method stub
currentTag = qName;
if("书".equals(currentTag)){
book = new Book();
}
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
// TODO Auto-generated method stub
if("书名".equals(currentTag)){
String name = new String(ch,start,length);
book.setName(name);
}
if("作者".equals(currentTag)){
String author = new String(ch,start,length);
book.setAuthor(author);
}
if("售价".equals(currentTag)){
String price = new String(ch, start, length);
book.setPrice(price);
}
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
// TODO Auto-generated method stub
if(qName.equals("书")){
list.add(book);
book = null;
}
currentTag = null;//不加上会报java.lang.NullPointerException
}
public List getList() {
return list;
}
}
DOM4J解析XML文档
Dom4j是一个简单、灵活的开放源代码的库。Dom4j是由早期开发JDOM的人分离出来而后独立开发的。与JDOM不同的是,dom4j使用接口和抽象基类,虽然Dom4j的API相对要复杂一些,但它提供了比JDOM更好的灵活性。
Dom4j是一个非常优秀的Java XML
API,具有性能优异、功能强大和极易使用的特点。现在很多软件采用的Dom4j,例如Hibernate,包括sun公司自己的JAXM也用了Dom4j。- 使用Dom4j开发,需下载dom4j相应的jar文件。
Document对象
DOM4j中,获得Document对象的方式有三种:
1.读取XML文件,获得document对象
SAXReader reader = new SAXReader();
Document document = reader.read(new File("input.xml"));
2.解析XML形式的文本,得到document对象.
String text = "<members></members>";
Document document = DocumentHelper.parseText(text);
3.主动创建document对象.
Document document = DocumentHelper.createDocument();
//创建根节点
Element root = document.addElement("members");
节点对象
1.获取文档的根节点.
Element root = document.getRootElement();
2.取得某个节点的子节点.
Element element=node.element("书名");
3.取得节点的文字
String text=node.getText();
4.取得某节点下所有名为“member”的子节点,并进行遍历.
List nodes = rootElm.elements("member")
for (Iterator it = nodes.iterator(); it.hasNext();) {
Element elm = (Element) it.next();
// do something
}
5.对某节点下的所有子节点进行遍历.
for(Iterator it=root.elementIterator();it.hasNext();){
Element element = (Element) it.next();
// do something
}
6.在某节点下添加子节点.
Element ageElm = newMemberElm.addElement("age");
7.设置节点文字.
element.setText("29");
8.删除某节点.
//childElm是待删除的节点,parentElm是其父节点
parentElm.remove(childElm);
9.添加一个CDATA节点.
Element contentElm = infoElm.addElement("content");
contentElm.addCDATA(diary.getContent());
节点对象属性
1.取得某节点下的某属性
Element root=document.getRootElement();
//属性名name
Attribute attribute=root.attribute("size");
2.取得属性的文字
String text=attribute.getText();
3.删除某属性
Attribute attribute=root.attribute("size");
root.remove(attribute);
4.遍历某节点的所有属性
Element root=document.getRootElement();
for(Iterator it=root.attributeIterator();it.hasNext();){
Attribute attribute = (Attribute) it.next();
String text=attribute.getText();
System.out.println(text);
}
5.设置某节点的属性和文字.
newMemberElm.addAttribute("name", "sitinspring");
6.设置属性的文字
Attribute attribute=root.attribute("name"); attribute.setText("sitinspring");
将文档写入XML文件
1.文档中全为英文,不设置编码,直接写入的形式.
XMLWriter writer = new XMLWriter(new FileWriter("output.xml"));
writer.write(document);
writer.close();
2.文档中含有中文,设置编码格式写入的形式.
OutputFormat format = OutputFormat.createPrettyPrint();// 指定XML编码
format.setEncoding("GBK");
XMLWriter writer = new XMLWriter(newFileWriter("output.xml"),format);
writer.write(document);
writer.close();
Dom4j在指定位置插入节点
- 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);
//更新document
字符串与XML的转换
- 1.将字符串转化为XML
String text = "<members> <member>sitinspring</member></members>";
Document document = DocumentHelper.parseText(text);
- 2.将文档或节点的XML转化为字符串.
SAXReader reader = new SAXReader();
Document document = reader.read(new File("input.xml"));
Element root=document.getRootElement();
String docXmlText=document.asXML();
String rootXmlText=root.asXML();
Element memberElm=root.element("member");
String memberXmlText=memberElm.asXML();
DOM4J编程
- 读取xml
//读取xml文档数据:<书名>Java就业培训教程</书名>
@Test
public void read() throws Exception{
SAXReader reader = new SAXReader();
Document document = reader.read(new File("src/book1.xml"));
Element root = document.getRootElement();
Element bookname = root.element("书").element("书名");
System.out.println(bookname.getText());
}
- 读取xml属性
//<书 name="yyyyyyy">
@Test
public void readAttr() throws Exception{
SAXReader reader = new SAXReader();
Document document = reader.read(new File("src/book1.xml"));
Element root = document.getRootElement();
String value = root.element("书").attributeValue("name");
System.out.println(value);
}
- 向xml中添加元素
//向xml文档中添加<售价>19元</售价>
@Test
public void add() throws Exception{
SAXReader reader = new SAXReader();
Document document = reader.read(new File("src/book1.xml"));
Element price = DocumentHelper.createElement("售价");
price.setText("19元");
document.getRootElement().element("书").add(price);
OutputFormat format = OutputFormat.createPrettyPrint();
format.setEncoding("UTF-8");
XMLWriter writer = new XMLWriter(new FileOutputStream("src/book1.xml"),format);//FileOutputStream 查格式输入器format的码表"UTF-8"
writer.write(document); //utf-8
writer.close();
}
<?xml version="1.0" encoding="UTF-8"?>
<书架>
<书 name="yyyyyyy">
<书名>Java就业培训教程</书名>
<作者>张孝祥</作者>
<售价>19元</售价>
<售价>19元</售价>
</书>
<书>
<书名>JavaScript网页开发</书名>
<作者>黎活明</作者>
<售价>28.00元</售价>
</书>
</书架>
- dom4j保存数据的乱码问题
//向xml文档中添加<售价>19元</售价>
@Test
public void add() throws Exception{
SAXReader reader = new SAXReader();
Document document = reader.read(new File("src/book1.xml"));
Element price = DocumentHelper.createElement("售价");
price.setText("19元");
document.getRootElement().element("书").add(price);
XMLWriter writer = new XMLWriter(new FileWriter("src/book1.xml"));//默认查gb2312码表
writer.write(document);
writer.close();
}
结果为乱码:
<?xml version="1.0" encoding="UTF-8"?>
<���>
<�� name="yyyyyyy">
<����>Java��ҵ��ѵ�̳�</����>
<����>����</����>
<�ۼ�>19Ԫ</�ۼ�>
<�ۼ�>19Ԫ</�ۼ�><�ۼ�>19Ԫ</�ۼ�></��>
<��>
<����>JavaScript��ҳ����</����>
<����>�����</����>
<�ۼ�>28.00Ԫ</�ۼ�>
</��>
</���>
修改为如下:
//向xml文档中添加<售价>19元</售价>
@Test
public void add() throws Exception{
SAXReader reader = new SAXReader();
Document document = reader.read(new File("src/book1.xml"));
Element price = DocumentHelper.createElement("售价");
price.setText("19元");
document.getRootElement().element("书").add(price);
OutputFormat format = OutputFormat.createPrettyPrint();
format.setEncoding("gb2312");
XMLWriter writer = new XMLWriter(new FileWriter("src/book1.xml"),format);
writer.write(document); //gb2312
writer.close();
}
<?xml version="1.0" encoding="gb2312"?>
<书架>
<书 name="yyyyyyy">
<书名>Java就业培训教程</书名>
<作者>张孝祥</作者>
<售价>19元</售价>
<售价>19元</售价>
</书>
<书>
<书名>JavaScript网页开发</书名>
<作者>黎活明</作者>
<售价>28.00元</售价>
</书>
</书架>
已下这种也可以解决乱码问题:
//向xml文档中添加<售价>19元</售价>
@Test
public void add() throws Exception{
SAXReader reader = new SAXReader();
Document document = reader.read(new File("src/book1.xml"));
Element price = DocumentHelper.createElement("售价");
price.setText("19元");
document.getRootElement().element("书").add(price);
XMLWriter writer = new XMLWriter(new OutputStreamWriter(new FileOutputStream("src/book1.xml"),"UTF-8"));
writer.write(document); //默认UTF-8
writer.close();
}
- 修改xml元素
//修改:<售价>19元</售价> 为209元
@Test
public void update() throws Exception{
SAXReader reader = new SAXReader();
Document document = reader.read(new File("src/book1.xml"));
Element price = (Element) document.getRootElement().element("书").elements("售价").get(0);
price.setText("209元");
OutputFormat format = OutputFormat.createPrettyPrint();
format.setEncoding("UTF-8");
XMLWriter writer = new XMLWriter(new FileOutputStream("src/book1.xml"),format);
writer.write(document); //utf-8
writer.close();
}
<?xml version="1.0" encoding="UTF-8"?>
<书架>
<书 name="yyyyyyy">
<书名>Java就业培训教程</书名>
<作者>张孝祥</作者>
<售价>209元</售价>
</书>
<书>
<书名>JavaScript网页开发</书名>
<作者>黎活明</作者>
<售价>28.00元</售价>
</书>
</书架>
- 删除xml元素
//删除:<售价>209</售价>
@Test
public void delete() throws Exception{
SAXReader reader = new SAXReader();
Document document = reader.read(new File("src/book1.xml"));
Element price = (Element) document.getRootElement().element("书").elements("售价").get(0);
price.getParent().remove(price);
OutputFormat format = OutputFormat.createPrettyPrint();
format.setEncoding("UTF-8");
XMLWriter writer = new XMLWriter(new FileOutputStream("src/book1.xml"),format);
writer.write(document); //utf-8
writer.close();
}
<?xml version="1.0" encoding="UTF-8"?>
<书架>
<书 name="yyyyyyy">
<书名>Java就业培训教程</书名>
<作者>张孝祥</作者>
</书>
<书>
<书名>JavaScript网页开发</书名>
<作者>黎活明</作者>
<售价>28.00元</售价>
</书>
</书架>
- 向指定位置增加售价结点
//向指定位置增加售价结点
@Test
public void add2() throws Exception{
SAXReader reader = new SAXReader();
Document document = reader.read(new File("src/book1.xml"));
Element price = DocumentHelper.createElement("售价");
price.setText("19元");
List list = document.getRootElement().element("书").elements();
list.add(1, price);
OutputFormat format = OutputFormat.createPrettyPrint();
format.setEncoding("UTF-8");
XMLWriter writer = new XMLWriter(new FileOutputStream("src/book1.xml"),format);
writer.write(document); //utf-8
writer.close();
}
<?xml version="1.0" encoding="UTF-8"?>
<书架>
<书 name="yyyyyyy">
<书名>Java就业培训教程</书名>
<售价>19元</售价>
<作者>张孝祥</作者>
</书>
<书>
<书名>JavaScript网页开发</书名>
<作者>黎活明</作者>
<售价>28.00元</售价>
</书>
</书架>
- XPath提取xml文档数据
@Test
public void findWithXpath() throws Exception{
SAXReader reader = new SAXReader();
Document document = reader.read(new File("src/book1.xml"));
Element e = (Element) document.selectNodes("//书名").get(1);
System.out.println(e.getText());
}
user.xml
<?xml version="1.0" encoding="UTF-8"?>
<users>
<user username="aaa" password="123"/>
<user username="bbb" password="123"/>
<user username="ccc" password="123"/>
</users>
@Test
public void findUser() throws Exception{
String username = "aaa";
String password = "1233";
SAXReader reader = new SAXReader();
Document document = reader.read(new File("src/users.xml"));
Element e = (Element) document.selectSingleNode("//user[@username='"+username+"' and @password='"+password+"']");
if(e!=null){
System.out.println("让用户登陆成功!!");
}else{
System.out.println("用户名和密码不正确!!");
}
}
}
XPath
详情参考:http://www.w3school.com.cn/xpath/index.asp
917

被折叠的 条评论
为什么被折叠?



