Java DOM簡(jiǎn)介

2018-02-12 19:19 更新

Java XML教程 - Java DOM簡(jiǎn)介


DOM是標(biāo)準(zhǔn)的樹(shù)結(jié)構(gòu),其中每個(gè)節(jié)點(diǎn)包含來(lái)自XML結(jié)構(gòu)的一個(gè)組件。

XML文檔中兩種最常見(jiàn)的節(jié)點(diǎn)類型是元素節(jié)點(diǎn)和文本節(jié)點(diǎn)。

使用Java DOM API,我們可以創(chuàng)建節(jié)點(diǎn),刪除節(jié)點(diǎn),更改其內(nèi)容,并遍歷節(jié)點(diǎn)層次結(jié)構(gòu)。

何時(shí)使用DOM

文檔對(duì)象模型標(biāo)準(zhǔn)是為XML文檔操作而設(shè)計(jì)的。

DOM的用意是語(yǔ)言無(wú)關(guān)的。Java的DOM解析器沒(méi)有利用Java的面向?qū)ο蟮奶匦?/span>優(yōu)勢(shì)。

混合內(nèi)容模型

文本和元素在DOM層次結(jié)構(gòu)中混合。這種結(jié)構(gòu)在DOM模型中稱為混合內(nèi)容。

例如,我們有以下xml結(jié)構(gòu):

<yourTag>This is an <bold>important</bold> test.</yourTag>

DOM節(jié)點(diǎn)的層級(jí)如下,其中每行代表一個(gè)節(jié)點(diǎn):

ELEMENT: yourTag
   + TEXT: This is an
   + ELEMENT: bold
     + TEXT: important
   + TEXT: test.

yourTag 元素包含文本,后跟一個(gè)子元素,后跟另外的文本。


節(jié)點(diǎn)類型

為了支持混合內(nèi)容,DOM節(jié)點(diǎn)非常簡(jiǎn)單。標(biāo)簽元素的“內(nèi)容"標(biāo)識(shí)它是的節(jié)點(diǎn)的類型。

例如,<yourTag> 節(jié)點(diǎn)內(nèi)容是元素 yourTag的名稱。

DOM節(jié)點(diǎn)API定義 nodeValue(), nodeType() nodeName()方法。

對(duì)于元素節(jié)點(diǎn)< yourTag> nodeName()返回yourTag,而nodeValue()返回null。

對(duì)于文本節(jié)點(diǎn) + TEXT:這是一個(gè)nodeName()返回#text,nodeValue()返回“This is an"。

例子

以下代碼顯示了如何使用DOM解析器來(lái)解析xml文件并獲取一個(gè) org.w3c.dom.Document 對(duì)象。

import java.io.File;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;

public class Main {

  public static void main(String[] args) throws Exception {
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    DocumentBuilder db = null;
    db = dbf.newDocumentBuilder();
    Document doc = db.parse(new File("games.xml"));
  }
}

例2

以下代碼顯示如何執(zhí)行DOM轉(zhuǎn)儲(chǔ)。

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

public class Main{
  static public void main(String[] arg) throws Exception{
    String filename = "input.xml";
    boolean validate = true;
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    dbf.setValidating(validate);
    dbf.setNamespaceAware(true);
    dbf.setIgnoringElementContentWhitespace(true);

    DocumentBuilder builder = dbf.newDocumentBuilder();
    builder.setErrorHandler(new MyErrorHandler());
    InputSource is = new InputSource(filename);
    Document doc = builder.parse(is);
    TreeDumper td = new TreeDumper();
    td.dump(doc);
  }
}
class TreeDumper {
    public void dump(Document doc) {
        dumpLoop((Node)doc,"");
    }
    private void dumpLoop(Node node,String indent) {
        switch(node.getNodeType()) {
        case Node.CDATA_SECTION_NODE:
            System.out.println(indent + "CDATA_SECTION_NODE");
            break;
        case Node.COMMENT_NODE:
            System.out.println(indent + "COMMENT_NODE");
            break;
        case Node.DOCUMENT_FRAGMENT_NODE:
            System.out.println(indent + "DOCUMENT_FRAGMENT_NODE");
            break;
        case Node.DOCUMENT_NODE:
            System.out.println(indent + "DOCUMENT_NODE");
            break;
        case Node.DOCUMENT_TYPE_NODE:
            System.out.println(indent + "DOCUMENT_TYPE_NODE");
            break;
        case Node.ELEMENT_NODE:
            System.out.println(indent + "ELEMENT_NODE");
            break;
        case Node.ENTITY_NODE:
            System.out.println(indent + "ENTITY_NODE");
            break;
        case Node.ENTITY_REFERENCE_NODE:
            System.out.println(indent + "ENTITY_REFERENCE_NODE");
            break;
        case Node.NOTATION_NODE:
            System.out.println(indent + "NOTATION_NODE");
            break;
        case Node.PROCESSING_INSTRUCTION_NODE:
            System.out.println(indent + "PROCESSING_INSTRUCTION_NODE");
            break;
        case Node.TEXT_NODE:
            System.out.println(indent + "TEXT_NODE");
            break;
        default:
            System.out.println(indent + "Unknown node");
            break;
        }

        NodeList list = node.getChildNodes();
        for(int i=0; i<list.getLength(); i++)
            dumpLoop(list.item(i),indent + "   ");

    }
}
class MyErrorHandler implements ErrorHandler {
  public void warning(SAXParseException e) throws SAXException {
    show("Warning", e);
    throw (e);
  }

  public void error(SAXParseException e) throws SAXException {
    show("Error", e);
    throw (e);
  }

  public void fatalError(SAXParseException e) throws SAXException {
    show("Fatal Error", e);
    throw (e);
  }

  private void show(String type, SAXParseException e) {
    System.out.println(type + ": " + e.getMessage());
    System.out.println("Line " + e.getLineNumber() + " Column "
        + e.getColumnNumber());
    System.out.println("System ID: " + e.getSystemId());
  }
}

錯(cuò)誤處理程序

以下代碼顯示了如何在使用DOM解析器解析XML時(shí)處理錯(cuò)誤。

import java.io.IOException; 

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

public class DOMCheck {
  static public void main(String[] arg) {
    boolean validate = true;

    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    dbf.setValidating(validate);
    dbf.setNamespaceAware(true);

    try {
      DocumentBuilder builder = dbf.newDocumentBuilder();
      builder.setErrorHandler(new MyErrorHandler());
      InputSource is = new InputSource("person.xml");
      Document doc = builder.parse(is);
    } catch (SAXException e) {
      System.out.println(e);
    } catch (ParserConfigurationException e) {
      System.err.println(e);
    } catch (IOException e) {
      System.err.println(e);
    }
  }
}

class MyErrorHandler implements ErrorHandler {
  public void warning(SAXParseException e) throws SAXException {
    show("Warning", e);
    throw (e);
  }

  public void error(SAXParseException e) throws SAXException {
    show("Error", e);
    throw (e);
  }

  public void fatalError(SAXParseException e) throws SAXException {
    show("Fatal Error", e);
    throw (e);
  }

  private void show(String type, SAXParseException e) {
    System.out.println(type + ": " + e.getMessage());
    System.out.println("Line " + e.getLineNumber() + " Column " + e.getColumnNumber());
    System.out.println("System ID: " + e.getSystemId());
  }
}

例3

以下代碼顯示了如何遞歸訪問(wèn)DOM樹(shù)中的所有節(jié)點(diǎn)。

import java.io.File;

import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class Main {
  public static void main(String[] argv) throws Exception{
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    factory.setValidating(true);

    factory.setExpandEntityReferences(false);

    Document doc = factory.newDocumentBuilder().parse(new File("file.xml"));

    visit(doc, 0);
  }
  public static void visit(Node node, int level) {
    NodeList list = node.getChildNodes();
    for (int i = 0; i < list.getLength(); i++) {
      Node childNode = list.item(i);
      visit(childNode, level + 1);
    }
  }
}

例4

下面的代碼顯示了如何將XML片段轉(zhuǎn)換為DOM片段。

import java.io.File;
import java.io.StringReader;

import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.DocumentFragment;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.InputSource;

public class Main {
  public static void main(String[] argv) throws Exception {
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    factory.setValidating(true);

    Document doc = factory.newDocumentBuilder().parse(new File("infilename.xml"));

    String fragment = "<fragment>aaa</fragment>";

    factory = DocumentBuilderFactory.newInstance();
    Document d = factory.newDocumentBuilder().parse(new InputSource(new StringReader(fragment)));

    Node node = doc.importNode(d.getDocumentElement(), true);

    DocumentFragment docfrag = doc.createDocumentFragment();

    while (node.hasChildNodes()) {
      docfrag.appendChild(node.removeChild(node.getFirstChild()));
    }

    Element element = doc.getDocumentElement();
    element.appendChild(docfrag);
  }

}

例5

下面的代碼顯示了如何解析XML字符串:使用DOM和StringReader。

import java.io.StringReader;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.CharacterData;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

public class Main {
  public static void main(String arg[]) throws Exception{
    String xmlRecords = "<data><employee><name>A</name>"
        + "<title>Manager</title></employee></data>";

    DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
    InputSource is = new InputSource();
    is.setCharacterStream(new StringReader(xmlRecords));

    Document doc = db.parse(is);
    NodeList nodes = doc.getElementsByTagName("employee");

    for (int i = 0; i < nodes.getLength(); i++) {
      Element element = (Element) nodes.item(i);

      NodeList name = element.getElementsByTagName("name");
      Element line = (Element) name.item(0);
      System.out.println("Name: " + getCharacterDataFromElement(line));

      NodeList title = element.getElementsByTagName("title");
      line = (Element) title.item(0);
      System.out.println("Title: " + getCharacterDataFromElement(line));
    }

  }

  public static String getCharacterDataFromElement(Element e) {
    Node child = e.getFirstChild();
    if (child instanceof CharacterData) {
      CharacterData cd = (CharacterData) child;
      return cd.getData();
    }
    return "";
  }
}

上面的代碼生成以下結(jié)果。

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)