学习笔记 --XML编程

XML编程(CRUD)

XML解析技术概述

XML解析方式分为两种:domsax

dom(Document Object Model, 即文档对象模型) W3C 组织推荐的处理 XML 的一种方式。

sax (Simple API for XML) 不是官方标准,但它是 XML 社区事实上的标准,几乎所有的 XML 解析器都支持它。

XML解析器

CrimsonXerces Aelfred2

XML解析开发包

JaxpJdomdom4j

 

JAXP

JAXP 开发包是J2SE的一部分,它由javax.xmlorg.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解析器在解析XML文档时,会把文档中的所有元素,按照其出现的层次关系,解析成一个个Node对象(节点)

          dom中,节点之间关系如下:

         位于一个节点之上的节点是该节点的父节点(parent)

         一个节点之下的节点是该节点的子节点(children

         同一层次,具有相同父节点的节点是兄弟节点(sibling

         一个节点的下一个层次的节点集合是节点后代(descendant)

         父、祖父节点及所有位于节点上面的,都是节点的祖先(ancestor)

 

Node对象

l       Node对象提供了一系列常量来代表结点的类型,当开发人员获得某个Node类型后,就可以把Node节点转换成相应的节点对象(Node的子类对象),以便于调用其特有的方法。(查看API文档)

l       Node对象提供了相应的方法去获得它的父结点或子结点。编程人员通过这些方法就可以读取整个XML文档的内容、或添加、修改、删除XML文档的内容了。

 

 

/**

 * 使用jaxpxml文档进行dom解析

 * @param args

 * @throws Exception

 */

1、以如下格式的exam.xml文件为例

<?xml version="1.0" encoding="UTF-8"?>

<书架>

       <>

              <书名 name="bbb" password="123">Java就业培训教程</书名>

              <作者>黎活明</作者>

              <售价>59</售价>

              <售价>39.00</售价>

       </>

       <>

              <书名>JavaScript网页开发</书名>

              <作者>张孝祥</作者>

              <售价>28.00</售价>

       </>

</书架>

 

 

public static void main(String[] args) throws Exception {

             

              //1.得到创建解析器的工厂

              DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

             

              //2.得到解析器

              DocumentBuilder builder = factory.newDocumentBuilder();

             

              //解析xml文档

              Document document = builder.parse(new File("src/book.xml"));

             

              //find(document);

              list(document);

}

      

//读取数据

public static void find(Document document){

             

       NodeList list = document.getElementsByTagName("书名");

       Node node = list.item(0);

       String  content = node.getTextContent();

       System.out.println(content);

             

}

      

 

//写入数据

public static void add(Document document) throws TransformerException{

       //1.创建节点

       Node price = document.createElement("售价");

       price.setTextContent("59");

             

       //2.找到要插入到哪个父亲下面

       Node book = document.getElementsByTagName("").item(0);

             

       //3.调用父亲的方法进行插入

       book.appendChild(price);

             

       //4.要把更新后的内存重新写入到xml

             

       TransformerFactory factory = TransformerFactory.newInstance();

       Transformer former = factory.newTransformer();

former.transform(new DOMSource(document),new StreamResult(new File("src/book.xml")));

      

System.out.println("插入成功");

             

}

      

//写入数据2

public static void add2(Document document) throws TransformerException{

       //1.创建节点

       Node price = document.createElement("售价");

       price.setTextContent("59");

 

       //2.找到要插入到哪个父亲下面

       Node book = document.getElementsByTagName("").item(0);

      

       //3.找到参照节点

       Node refNode = document.getElementsByTagName("售价").item(0);

      

       //3.调用父亲的方法进行插入

       book.insertBefore(price, refNode);

             

       //4.要把更新后的内存重新写入到xml      

       TransformerFactory factory = TransformerFactory.newInstance();

       Transformer former = factory.newTransformer();

former.transform(new DOMSource(document),new StreamResult(new File("src/book.xml")));

             

       System.out.println("插入成功");

}

      

//修改:把第一本书的作者修改为黎活明

public static void update(Document document) throws Exception{

       document.getElementsByTagName("作者").item(0).setTextContent("黎活明");

       TransformerFactory factory = TransformerFactory.newInstance();

       Transformer former = factory.newTransformer();

former.transform(new DOMSource(document),new StreamResult(new File("src/book.xml")));

             

}

      

      

//删除:把第二本书删掉

public static void delete(Document document) throws Exception{

       /*Node root = document.getElementsByTagName("书架").item(0);

       Node book = document.getElementsByTagName("").item(1);

       root.removeChild(book);*/

             

       Node book = document.getElementsByTagName("").item(1);

       book.getParentNode().removeChild(book);

             

       TransformerFactory factory = TransformerFactory.newInstance();

       Transformer former = factory.newTransformer();

former.transform(new DOMSource(document),new StreamResult(new File("src/book.xml")));

}

      

//遍历xml文档所有节点

public static void list(Document document){

       Node root = document.getElementsByTagName("书架").item(0);

       listNode(root);

}

      

public static void listNode(Node node){

       System.out.println(node.getNodeName());

       NamedNodeMap map = node.getAttributes();

             

       for(int i=0;map!=null && i<map.getLength();i++){  //null

              Attr attr = (Attr) map.item(i);

              String name = attr.getName();

              String value = attr.getValue();

              System.out.println(name + "=" + value);

}

             

             

       NodeList list = node.getChildNodes();

       for(int i=0;i<list.getLength();i++){

              Node child = list.item(i);

              listNode(child);

       }

}

 

//xml文档属性的增删改查

//获取<书名 name="aaa">  name属性值

@Test

public void test1() throws Exception{

 

Document document =DocumentBuilderFactory.newInstance()

.newDocumentBuilder().parse(new File("src/book.xml"));

       Element e = (Element) document.getElementsByTagName("书名").item(0);

             

       String value = e.getAttribute("name");

       System.out.println(value);

}

 

//向书名节点中添加一个password属性

@Test

public void test2() throws Exception{

             

       Document document = DocumentBuilderFactory.newInstance()

.newDocumentBuilder().parse(new File("src/book.xml"));

       Element node = (Element) document.getElementsByTagName("书名").item(0);

             

       //创建要添加的属性

       /*

       Attr attr = document.createAttribute("password");

       attr.setValue("123");

       node.setAttributeNode(attr);

       */

       node.setAttribute("email", "aa@sina.com");

             

             

       TransformerFactory factory = TransformerFactory.newInstance();

       Transformer former = factory.newTransformer();

former.transform(new DOMSource(document),new StreamResult(new File("src/book.xml")));

             

}

      

//删除属性

@Test

public void test3() throws Exception{

       Document document = DocumentBuilderFactory.newInstance()

.newDocumentBuilder().parse(new File("src/book.xml"));

       Element e = (Element) document.getElementsByTagName("书名").item(0);

       e.removeAttribute("email");

 

       TransformerFactory factory = TransformerFactory.newInstance();

       Transformer former = factory.newTransformer();

former.transform(new DOMSource(document),new StreamResult(new File("src/book.xml")));

}

 

更新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 文档,涉及两个部分:解析器和事件处理器:

         解析器可以使用JAXPAPI创建,创建出SAX解析器后,就可以指定解析器去解析某个XML文档。

         解析器采用SAX方式在解析某个XML文档时,它只要解析到XML文档的一个组成部分,都会去调用事件处理器的一个方法,解析器在调用事件处理器的方法时,会把当前解析到的xml文件内容作为方法的参数传递给事件处理器。

         事件处理器由程序员编写,程序员通过事件处理器中方法的参数,就可以很轻松地得到sax解析器解析到的数据,从而可以决定如何对数据进行处理。

 

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解析入门

 * @param args

 * @throws SAXException

 * @throws Exception

 */

public static void main(String[] args) throws Exception, SAXException {

 

              //1.得到工厂

              SAXParserFactory factory = SAXParserFactory.newInstance();

             

              //2.创建解析器

              SAXParser sp = factory.newSAXParser();

             

              //3.获得读取器

              XMLReader reader = sp.getXMLReader();

             

              //4.设置内容处理器

              reader.setContentHandler(new NameHandler());

             

              //5.读取xml文档

              reader.parse("src/book.xml");

       }

}

 

class NameHandler extends DefaultHandler{

 

       private String currentNode = null;

       private int index = 1;  //记住想获取第几个作者的值

       private int count = 0;  //记住当前解析到的是第几个作者

       public void startElement(String uri, String localName, String name,

                     Attributes atts) throws SAXException {

              if(name.equals("作者")){

                     currentNode = "作者";

                     count++;

       }

}

public void characters(char[] ch, int start, int length)

                     throws SAXException {

       if(currentNode!=null && currentNode.equals("作者") && count==index){

              String content = new String(ch,start,length);

              System.out.println(content);

       }

}

      

public void endElement(String uri, String localName, String name)

       throws SAXException {

       currentNode = null;

}

 

 

DOM4J解析XML文档

Dom4j是一个简单、灵活的开放源代码的库。Dom4j是由早期开发JDOM的人分离出来而后独立开发的。与JDOM不同的是,dom4j使用接口和抽象基类,虽然Dom4jAPI相对要复杂一些,但它提供了比JDOM更好的灵活性。

Dom4j是一个非常优秀的Java XML API,具有性能优异、功能强大和极易使用的特点。现在很多软件采用的Dom4j,例如Hibernate,包括sun公司自己的JAXM也用了Dom4j

使用Dom4j开发,需下载dom4j相应的jar文件。

 

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);

 

3.遍历某节点的所有属性
   Element root=document.getRootElement();    
   for(Iterator it=root.attributeIterator();it.hasNext();){
         Attribute attribute = (Attribute) it.next();
         String text=attribute.getText();
         System.out.println(text);
    }

 

4.设置某节点的属性和文字.
   newMemberElm.addAttribute("name", "sitinspring");

 

5.设置属性的文字
   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();

 

 

 

 

//dom4jcrud

public class Demo1 {

      

       //遍历xml文档

       @Test

       public void test1() throws Exception{

              SAXReader reader = new SAXReader();

              Document document = reader.read(new File("src/book.xml"));

              list(document.getRootElement());

       }

      

       public void list(Element node){

              System.out.println(node.getName());

              List<Node> list = node.elements();

              for(Node child : list){

                     if(child instanceof Element){

                            list((Element)child);

                     }

              }

       }

      

      

       //读取售价的值

       @Test

       public void read() throws Exception{

              SAXReader reader = new SAXReader();

              Document document = reader.read(new File("src/book.xml"));

             

              Element root = document.getRootElement();

              String content = root.element("").element("售价").getText();

              System.out.println(content);

       }

      

       //xml文档中添加一个:<售价>39</售价>

       @Test

       public void write() throws Exception{

             

              SAXReader reader = new SAXReader();

              Document document = reader.read(new File("src/book.xml"));

             

              Element price = DocumentHelper.createElement("售价");

              price.setText("39");

             

              Element root = document.getRootElement();

              root.element("").add(price);

             

             

              OutputFormat format = OutputFormat.createPrettyPrint();

              format.setEncoding("gb2312");

              XMLWriter writer = new XMLWriter(new FileOutputStream("src/book.xml"),format);

              writer.write(document);

              writer.close();

             

             

              /*OutputFormat format = OutputFormat.createPrettyPrint();

              format.setEncoding("gb2312");

              //document-->utf-8

              FileWriter fw = new FileWriter("src/book.xml");

             

              XMLWriter writer = new XMLWriter(fw,format);

              writer.write(document);

              writer.close();*/

              /*   

XMLWriter writer = new XMLWriter(

new OutputStreamWriter(new FileOutputStream("src/book.xml"),"UTF-8"),format);

              writer.write(document);

              writer.close();*/

       }

      

       //向指定位置插入:<售价>39</售价>

       @Test

       public void write2() throws Exception{

             

              SAXReader reader = new SAXReader();

              Document document = reader.read(new File("src/book.xml"));

             

              Element price = DocumentHelper.createElement("售价");

              price.setText("39");

             

              Element book = document.getRootElement().element("");

              List list = book.elements();  //

              list.add(2, price);  //向指定位置插入

             

             

              OutputFormat format = OutputFormat.createPrettyPrint();

              format.setEncoding("gb2312");

              XMLWriter writer = new XMLWriter(new FileOutputStream("src/book.xml"),format);

              writer.write(document);

              writer.close();

       }

      

       //删除售价节点:

       @Test

       public void delete() throws Exception{

              SAXReader reader = new SAXReader();

              Document document = reader.read(new File("src/book.xml"));

             

              Element price = document.getRootElement().element("").element("售价");

              price.getParent().remove(price);

             

              OutputFormat format = OutputFormat.createPrettyPrint();

              format.setEncoding("gb2312");

              XMLWriter writer = new XMLWriter(new FileOutputStream("src/book.xml"),format);

              writer.write(document);

              writer.close();

       }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值