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文档,得到代表文档的documentDocument 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);}}
}
- 查找某一个节点
//得到售价结点的值@Testpublic 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);}
- 添加节点
//向指定节点中增加孩子节点(售价节点)@Testpublic 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元</售价></书></书架>
//向指定位置上插入售价节点@Testpublic 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@Testpublic 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文档的售价结点@Testpublic 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文档属性@Testpublic 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文档属性@Testpublic 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文档@Testpublic 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.DOMSourc
e类来关联要转换的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.利用解析器得到readerXMLReader 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.利用解析器得到readerXMLReader 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;@Overridepublic void characters(char[] ch, int start, int length)throws SAXException {if(isOk==true && index==1){System.out.println(new String(ch,start,length));}}@Overridepublic void startElement(String uri, String localName, String name,Attributes attributes) throws SAXException {if(name.equals("售价")){isOk = true;}}@Overridepublic 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.利用解析器得到readerXMLReader 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; //当前解析到的是第几个标签@Overridepublic void startElement(String uri, String localName, String name,Attributes attributes) throws SAXException {currentTag = name;if(currentTag.equals("作者")){currentNumber ++;}}@Overridepublic void characters(char[] ch, int start, int length)throws SAXException {if("作者".equals(currentTag) && currentNumber == needNumber){System.out.println(new String(ch,start,length));}}@Overridepublic 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;}@Overridepublic 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.利用解析器得到readerXMLReader 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;@Overridepublic void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {// TODO Auto-generated method stubcurrentTag = qName;if("书".equals(currentTag)){book = new Book();}}@Overridepublic void characters(char[] ch, int start, int length) throws SAXException {// TODO Auto-generated method stubif("书名".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);}}@Overridepublic void endElement(String uri, String localName, String qName) throws SAXException {// TODO Auto-generated method stubif(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();
//属性名nameAttribute 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就业培训教程</书名>@Testpublic 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">@Testpublic 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元</售价>@Testpublic 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-8writer.close();}
<?xml version="1.0" encoding="UTF-8"?><书架> <书 name="yyyyyyy"> <书名>Java就业培训教程</书名> <作者>张孝祥</作者> <售价>19元</售价> <售价>19元</售价></书> <书> <书名>JavaScript网页开发</书名> <作者>黎活明</作者> <售价>28.00元</售价> </书>
</书架>
- dom4j保存数据的乱码问题
//向xml文档中添加<售价>19元</售价>@Testpublic 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元</售价>@Testpublic 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元</售价>@Testpublic 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元@Testpublic 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-8writer.close();}
<?xml version="1.0" encoding="UTF-8"?><书架> <书 name="yyyyyyy"> <书名>Java就业培训教程</书名> <作者>张孝祥</作者> <售价>209元</售价> </书> <书> <书名>JavaScript网页开发</书名> <作者>黎活明</作者> <售价>28.00元</售价> </书>
</书架>
- 删除xml元素
//删除:<售价>209</售价>@Testpublic 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-8writer.close();}
<?xml version="1.0" encoding="UTF-8"?><书架> <书 name="yyyyyyy"> <书名>Java就业培训教程</书名> <作者>张孝祥</作者> </书> <书> <书名>JavaScript网页开发</书名> <作者>黎活明</作者> <售价>28.00元</售价> </书>
</书架>
- 向指定位置增加售价结点
//向指定位置增加售价结点@Testpublic 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-8writer.close();}
<?xml version="1.0" encoding="UTF-8"?><书架> <书 name="yyyyyyy"> <书名>Java就业培训教程</书名> <售价>19元</售价><作者>张孝祥</作者> </书> <书> <书名>JavaScript网页开发</书名> <作者>黎活明</作者> <售价>28.00元</售价> </书>
</书架>
- XPath提取xml文档数据
@Testpublic 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>
@Testpublic 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
dom4j参考资料
https://dom4j.github.io/