XML编程—CRUD

一、 JAXP 简介

JAXP 使得用 Java 开发处理 XML 数据的应用程序非常容易,JAXP 包括语法分析器、标准 SAX与 DOM,可以选择以事件流或建立对象表示来解析数据。JAXP 1.1 版本还支持XSLT标准, 可以控制数据的表示, 并可以将数据转换成其他的XML文件或格式, 如HTML。JAXP 还提供对名称空间的支持,可以在没有命名冲突的情况下使用 DTD。

JAXP 提供的类和方法,可以让 Java 应用程序使用 DOM 解析或转换 XML 文件,在JDK 1.4支持的JAXP API 1.1版支持XML, 建议规格有DOM Level 2、 XSLT 1.0和SAX 2.0。其解析文档对象模型的相关套件,见表。

表  JAXP API 1.1解析文档对象模型的相关套件

套    件

说    明

Javax.xml.parsers

提供处理XML 文件的类

Javax.xml.transform

提供处理XSLT文件的类

org.xml.sax

这是SAX解析器,提供以事件驱动方式解析XML文件的AP

org.xml.saxhelpers

提供解析错误处理的相关类,可以帮助程序设计者使用SAX API

org.w3c.dom

提供支持DOM建议规格的套件

二、加载 XML文档文件

    在 Java 程序中加载 XML文档文件,步骤如下。

1、首先需要导入相关的套件。

   import javax.xml.parsers.*;

import org.xml.sax.*;

import org.w3c.dom.*;

import java.io.*;

其中org.xml.sax.*套件是解析错误处理的相关套件,此外因为XML文件属于文本文件,

所以导入文件处理的套件用 import java.io.*。

2、在 JAXP 中,DOM解析器称为 DocumentBulider,可以通过工厂类 DocumentBulider Factory获得,而 document 对象则可以通过类 DocumentBulider获得,使用 try catch 指令建立解析的错误处理。在建立 DocumentBulider对象后,可使用 parser方法解析加载 XML 文件,file 对象加载后就可以处理 XML 文件的结点内容。

3、获得接口类 document 实例后,就可以对 DOM 的文档树进行访问。如要遍历 DOM文档,首先要获得根结点,然后获得根结点的子结点列表。

//获得根结点

Element element=document.getDocumentElement(); 

//获得根结点的子结点列表

NodeList=element.getChildNodes();

三、XML编程——CRUD

    1、访问 XML元素和属性

    在 DOM 接口规范中,有 4 个基本接口:Document、Node、NodeList、Element。在这4 个基本接口中,Document 接口是对文档进行操作的入口,它是从 Node 接口继承过来的。Node 接口是其他大多数接口的父类,像 Document、Element、Text、Comment 等接口都是从 Node 接口继承过来的。NodeList 接口是一个结点的集合,它包含了某个结点中的所有子结点。下面对这几个接口分别做一些简单的介绍。

        Document 接口

Document 接口代表了整个 XML 文档,因此,它是整个文档树的根,提供了对文档中数据进行访问和操作的入口。通过 Document 结点,可以访问到文档中的其他结点,如处理指令、批注、文字等。

方法描述:

1) getDocumentElement(), Document文件对象使用该方法可获取XML文件的根结点; 

2) getElementsByTagName(),Document 使用标记名获取子结点,取出的结点是一个NodeList 对象。

        Node接口

Node 接口在整个 DOM 树中具有举足轻重的地位,DOM 接口中很大一部分接口是从Node 接口继承过来的,例如 Document、Element、Text、Comment 等接口。在 DOM 树中,Node 接口代表了树中的一个结点。

方法描述:

1) getChildNodes(),获取子结点的 NodeList 结点对象列表,即子结点数;

2) getNodeName(),返回结点名称,不同类型结点的值不同;

3) getNodeType(),返回结点类型的代码;

4) getNodeValue(),返回结点的值;

5) getFirstChild(),获取第一个子结点;

6) getNextSibling(),获取此结点的兄弟结点,即同级的下一个结点;

7) getLastChild(),获取最后一个子结点;

8) getParentNode(),获取父结点;

9) hasChildNodes(),Node 结点对象检查是否拥有子结点,是返回 true,否则为 false。

        NodeList接口

NodeList 接口提供了对结点集合的抽象定义, 它并不包含如何实现这个结点集的定义。NodeList 接口用于表示有顺序关系的一组结点,比如某个结点的子结点序列。其中的每个item 都可以通过一个索引来访问,该索引值从 0 开始。另外,它还出现在一些方法的返回值中。

方法描述:

(1) getLength(),可获取 NodeList 对象共有多少结点,即结点的个数;

(2) item(int),返回参数制定的结点对象,参数是结点对象的索引值。

       Element 接口

Element 接口是从 Node 接口继承过来的,它代表了 XML 文档中的元素。Element 接口提供了访问 DOM 树中元素内容与信息的途径,并给出了对 DOM 树中的元素进行遍历的支持。

方法描述:

(1) getElementsByTagName(string),通过标记名称获取元素;

(2) getTagName(),获取元素的标记的名称;

(3) getAttributes(string),获取元素的属性,是属性对象列表,属于 NamedNodeMap;

(4) getAttributeNode(string),通过属性的名字得到一个属性类型结点。

下面通过一个实例来说明如何使用上述对象和方法来解析 XML 文档。

Demo1.java代码清单如下:

package cn.csdn.xml;

import java.io.File;

import java.io.IOException;

import javax.xml.parsers.DocumentBuilder;

import javax.xml.parsers.DocumentBuilderFactory;

import javax.xml.parsers.ParserConfigurationException;

import org.junit.Test;

import org.w3c.dom.Document;

import org.w3c.dom.Node;

import org.w3c.dom.NodeList;

import org.xml.sax.SAXException;

public class Demo1 {

    @Test

    public void test() {

       DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

       dbf.setIgnoringComments(true);

       DocumentBuilder db;

       try {

           db = dbf.newDocumentBuilder();

           Document document = db.parse(new File("src//code2.xml"));

           Node root = document.getDocumentElement();

           NodeList list = root.getChildNodes();

           display(list);

       } catch (ParserConfigurationException e) {

           // TODO Auto-generated catch block

           e.printStackTrace();

       } catch (SAXException e) {

           // TODO Auto-generated catch block

           e.printStackTrace();

       } catch (IOException e) {

           // TODO Auto-generated catch block

           e.printStackTrace();

       }

    }

    public static void display(NodeList list) {

       if (list.getLength() == 0) {

           System.out.println("该结点没有子结点!");

       }

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

           Node node = list.item(i);

           // 获取结点的类型,可以是ElementNode,TextNode,DocumentNode等

           short nodetype = node.getNodeType();

           if (nodetype == Node.ELEMENT_NODE) {

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

              if (node.hasAttributes()) {

                  Node attribute = node.getAttributes().item(0);

                  System.out.println(attribute.getNodeName() + " "

                         + attribute.getNodeValue());

              }

              if (node.hasChildNodes()) {

                  display(node.getChildNodes());

              }

           }

           if (nodetype == Node.TEXT_NODE) {

              String txtName = node.getNodeName();

              // 取出text类型结点的值

              Node parent = node.getParentNode(); //此结点的父结点

              Node txtNode = parent.getChildNodes().item(0);

              String txtValue = txtNode.getNodeValue();

              if (txtValue.trim().length() > 0) {

                  System.out.println(txtName + " " + txtValue);

              }

           }

       }

    }

}

2、使用 DOM 创建 XML文档

        创建 XML 文档

可以使用 newDecument方法建立 XML 文档。

Document=db.newDecument();

        建立新的结点

使用 Document 对象的方法建立所需结点对象,见表。

建立新结点的方法

方     法

说    明

createElement(string)

建立XML元素的结点,参数为标记名称

createAttribute(string)

建立属性名称的属性结点,参数是属性名称

createCDATASection(string)

建立CDATA块,参数是文字内容

createComment(string)

建立注释文字结点,参数为注释文字内容

createTextNode(string)

建立文字结点,参数为内容

createEntityReference(string)

建立实体参考,参数为实体参考名称

createProcessingInstring(string,string)

建立PI结点,第一个参数是PI名称,第二个为值

        指定插入的位置

在建立好 XML 元素的对象后,可以使用 Node 结点对象的方法添加到 DOM 树中:

  • appendChild(newnode),新添加一个 newnode 结点;
  • insertBefore(newnode,befnode),将 newnode 结点插到 befnode 结点前。

        新增元素内容

使用 createTextNode方法建立文字结点后, 再使用 appendChild 方法将它添加到元素结点中。

        新增元素的属性

可以使用 setAttribute 方法给 Element 元素对象增加属性。

使用 DOM 对象创建 XML文件,代码清单如下:

package cn.csdn.xml;

import java.io.File;

import java.io.IOException;

import javax.xml.parsers.DocumentBuilder;

import javax.xml.parsers.DocumentBuilderFactory;

import javax.xml.parsers.ParserConfigurationException;

import javax.xml.transform.Transformer;

import javax.xml.transform.TransformerConfigurationException;

import javax.xml.transform.TransformerException;

import javax.xml.transform.TransformerFactory;

import javax.xml.transform.dom.DOMSource;

import javax.xml.transform.stream.StreamResult;

import org.junit.Test;

import org.w3c.dom.Document;

import org.w3c.dom.Element;

import org.w3c.dom.Node;

import org.xml.sax.SAXException;

public class Demo2 {

    // 使用DOM创建一个XML文档

    static Document document;

    @Test

    public void testAdd() {

       DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

       try {

           DocumentBuilder db = dbf.newDocumentBuilder();

           // 建立新的XML文档

           document = db.newDocument();

           // 建立根元素

           Element root = document.createElement("中国");

           document.appendChild(root);

           // 新增子元素 陕西省

           Element newchild = document.createElement("陕西省");

           root.appendChild(newchild);

           // 增加元素的内容

           newchild.appendChild(document.createTextNode("交通大学"));

           // 增加元素的属性

           newchild = (Element) root.getFirstChild();

           newchild.setAttribute("ID", "0x8905072");

           // 新增子元素 河北省

           newchild = document.createElement("河北省");

           root.appendChild(newchild);

           // 增加元素的内容

           newchild.appendChild(document.createTextNode("河北软件职业技术     学院"));

           // 新增子元素 北京市

           newchild = document.createElement("北京市");

           // 新增元素插入在根元素的最后一个节点前面

           root.insertBefore(newchild, root.getLastChild());

           // 新增文字节点

           Node text = document.createTextNode("中关村软件园");

           // 插入文字结点到根结点第一个子结点的兄弟结点,即第二子结点

           Node temp = root.getFirstChild();

           temp.getNextSibling().appendChild(text);

           TransformerFactory tff = TransformerFactory.newInstance();

           Transformer tf = tff.newTransformer();

           tf.transform(new DOMSource(document), new StreamResult(

                  "src//code.xml"));

       } catch (ParserConfigurationException e) {

           // TODO Auto-generated catch block

           e.printStackTrace();

       } catch (TransformerConfigurationException e) {

           // TODO Auto-generated catch block

           e.printStackTrace();

       } catch (TransformerException e) {

           // TODO Auto-generated catch block

           e.printStackTrace();

       }

    }

    @Test

    public void testIndexAdd() {

       DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

       dbf.setIgnoringComments(true);

       try {

           DocumentBuilder db = dbf.newDocumentBuilder();

           // 记载XML源文件

           document = db.parse(new File("src//code2.xml"));

       // 获取节点,因为要将新增的子元素插在元素“海淀”之前,所以这里获取根元素“北京”的节点

           Node node = document.getElementsByTagName("北京").item(0);

           // 新增子元素

           Element ele = document.createElement("昌平");

           ele.appendChild(document.createTextNode("O(∩_∩)O哈哈~"));

       node.insertBefore(ele, node.getFirstChild()); // 将新增子元素“昌平”插入元素“海淀”的前面

           // 新增子元素

           ele = document.createElement("新密");

           // 获取节点

           node = document.getElementsByTagName("郑州").item(0);

           // // 将新增子元素“新密”插入元素“商丘”的前面

       node.insertBefore(ele, node.getFirstChild()); //插入元素“商丘”之后,则为node.getLastChild();

           TransformerFactory tff = TransformerFactory.newInstance();

           Transformer tf = tff.newTransformer();

           tf.transform(new DOMSource(document), new StreamResult(

                  "src//code2.xml"));

       } catch (ParserConfigurationException e) {

           // TODO Auto-generated catch block

           e.printStackTrace();

       } catch (SAXException e) {

           // TODO Auto-generated catch block

           e.printStackTrace();

       } catch (IOException e) {

           // TODO Auto-generated catch block

           e.printStackTrace();

       } catch (TransformerConfigurationException e) {

           // TODO Auto-generated catch block

           e.printStackTrace();

       } catch (TransformerException e) {

           // TODO Auto-generated catch block

           e.printStackTrace();

       }

    }

}

3、使用DOM删除元素或属性

如要删除结点可使用 Node 结点的 removeChild 方法删除指定的结点,如要删除属性可使用 Element 元素对象的 removeAttribute  方法删除。

//删除第一个customer 结点

root.removeChild(Element)root.getElementsBytagName("customer").item(0);

   //删除属性

Element node=(Element)root.getFirstChild();

Node.removeAttribute("ID")

    看下面的代码片段。

    public void test1()throws Exception{

       DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

factory.setIgnoringElementContentWhitespace(true);

       DocumentBuilder builder  = factory.newDocumentBuilder();

       Document doc = builder.parse(new File("src//dom.xml"));

       Node node = doc.getElementsByTagName("海淀").item(0);

       node.removeChild(doc.getElementsByTagName("东北旺").item(2));

       TransformerFactory factory1 = TransformerFactory.newInstance();

      

       Transformer tformer = factory1.newTransformer();

       tformer.transform(new DOMSource(doc), new StreamResult("src//dom.xml"));

    }

4、使用DOM更改元素的值

    public void test2()throws Exception{

       DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

       factory.setIgnoringElementContentWhitespace(true);

       DocumentBuilder builder  = factory.newDocumentBuilder();

       Document doc = builder.parse(new File("src//dom.xml"));

       Node node1 = doc.getElementsByTagName("东北旺").item(0);

       node1.setTextContent("未知地区");

       TransformerFactory factory1 = TransformerFactory.newInstance();

       Transformer tformer = factory1.newTransformer();

       tformer.transform(new DOMSource(doc), new StreamResult("src//dom.xml"));

    }

以上案例使用的dom.xml代码清单如下:

    <?xml version="1.0" encoding="UTF-8" standalone="no"?><中国>

    <北京>

       <海淀>

           <上地>上地七街</上地>

           <中关村>鼎好</中关村>

           <东北旺>哈哈</东北旺>

       <东北旺/></海淀>

    </北京>

    <河南>

       <郑州>

           <商丘 id="attr" 人口="100万">商丘中学</商丘>

       </郑州>

       <安阳/>

    </河南>

    <河北>

       <石家庄 人口="2000万"/>

    </河北>

</中国>

四、小结

    本文主要介绍 Java 应用程序如何使用 DOM 处理 XML 文件。要创建 DOM 需要使用JAXP,JAXP使得用Java开发处理XML文件的应用程序非常容易,只要在Java程序中导入相关的套件, 如import javax.xml.parsers.*、 import org.xml.sax.*、 import org.w3c.dom.*、 import java.io.*,就可以使用它所提供的类和方法,让 Java 应用程序使用 DOM 加载 XML 文件,访问、增加和删除 XML元素和属性。

你可能感兴趣的:(java,html,编程,xml,dom)