zoukankan      html  css  js  c++  java
  • JDOM的使用

    最近的工作常常要和XML格式的文档或字符串打交道,发现用JDOM来做真是方便。可以实现XML应用程序的快速开发。
        在 JDOM 中,XML 元素就是 Element 的实例,XML 属性就是 Attribute 的实例,XML 文档本身就是 Document 的实例。
        因为 JDOM 对象就是像 Document、Element 和 Attribute 这些类的直接实例,因此创建一个新 JDOM 对象就如在 Java 语言中使用 new 操作符一样容易。JDOM 的使用是直截了当的。
        JDOM 使用标准的 Java 编码模式。只要有可能,它使用 Java new 操作符而不故弄玄虚使用复杂的工厂化模式,使对象操作即便对于初学用户也很方便。
       
        本文分两步对JDOM的应用加以介绍:XML创建 和 XML解析
    一、XML文档创建
        我们由零开始利用JDOM生成一个XML文档。最后的结果(样本文档)看起来象这样:
        <?xml version="1.0" encoding="UTF-8"?>
        <MyInfo comment="introduce myself">
            <name>kingwong</name>
            <sex value="male"/>
            <contact>
                <telephone>87654321</telephone>
            </contact>
        </MyInfo>
        1.以 MyInfo 为根元素创建文档
            Element rootElement = new Element("MyInfo");//所有的XML元素都是 Element 的实例。根元素也不例外:)
            Document myDocument = new Document(rootElement);//以根元素作为参数创建Document对象。一个Document只有一个根,即root元素。
        2.给根元素添加属性
            Attribute rootAttri = new Attribute("comment","introduce myself");//创建名为 commnet,值为 introduce myself 的属性。
            rootElement.setAttribute(rootAttri);//将刚创建的属性添加到根元素。
            这两行代码你也可以合成一行来写,象这样:
            rootElement.setAttribute(new Attribute("comment","introduce myself"));
            或者
            rootElement.setAttribute("comment","introduce myself");
        3.添加元素和子元素
            JDOM里子元素是作为 content(内容)添加到父元素里面去的,所谓content就是类似上面样本文档中<name></name>之间的东东,即kingwong。罗嗦了点是吧:)
            Element nameElement = new Element("name");//创建 name 元素
            nameElement.addContent("kingwong");//将kingwong作为content添加到name元素
     rootElement.addContent(nameElement);//将name元素作为content添加到根元素
     
     这三行你也可以合为一句,象这样:
     rootElement.addContent((Content)(new Element("name").addContent("kingwong")));//因为addContent(Content child)方法返回的是一个Parent接口,而Element类同时继承了Content类和实现了Parent接口,所以我们把它造型成Content。
     
            我们用同样的方法添加带属性的子元素<sex value="male"/>
            rootElement.addContent(new Element("sex").setAttribute("value","male"));//注意这里不需要转型,因为addAttribute(String name,String value)返回值就是一个 Element。
           
            同样的,我们添加<contract />元素到根元素下,用法上一样,只是稍微复杂了一些:
            rootElement.addContent((Content)(new Element("contact").addContent((Content)(new Element("telephone").addContent("87654321")))));
            如果你对这种简写形式还不太习惯,你完全可以分步来做,就象本节刚开始的时候一样。事实上如果层次比较多,写成分步的形式更清晰些,也不容易出错。
        4.删除子元素
            这个操作比较简单:
            rootElement.removeChild("sex");//该方法返回一个布尔值
           
            到目前为止,我们学习了一下JDOM文档生成操作。上面建立了一个样本文档,可是我们怎么知道对不对呢?因此需要输出来看一下。我们将JDOM生成的文档输出到控制台,使用 JDOM 的 XMLOutputter 类。
        5.  将 JDOM 转化为 XML 文本
            XMLOutputter xmlOut = new XMLOutputter("  ",true);
     try {
      xmlOut.output(myDocument,System.out);
     } catch (IOException e) {
      e.printStackTrace();
     }
     XMLOutputter 有几个格式选项。这里我们已指定希望子元素从父元素缩进两个空格,并且希望元素间有空行。
     new XMLOutputter(java.lang.String indent, boolean newlines)这个方法在最新版本中已经不建议使用。JDOM有一个专门的用来定义格式化输出的类:org.jdom.output.Format,如果你没有特殊的要求,有时候使用里面的几个静态方法(应该可以说是预定义格式)如 getPrettyFormat()就可以了。我们把上面的输出格式稍微改一下,就象这样:
     XMLOutputter xmlOut = new XMLOutputter(Format.getPrettyFormat()); 
        6.将JDOM文档转化为其他形式
            XMLOutputter 还可输出到 Writer 或 OutputStream。为了输出JDOM文档到一个文本文件,我们可以这样做:
            FileWriter writer = new FileWriter("/some/directory/myFile.xml");
            outputter.output(myDocument, writer);
            writer.close();
           
            XMLOutputter 还可输出到字符串,以便程序后面进行再处理:
            Strng outString = xmlOut.outputString(myDocument);
           
            当然,在输出的时候你不一定要输出所有的整个文档,你可以选择元素进行输出:
            xmlOut.output(rootElement.getChild("name"),System.out);
            一句话,JDOM非常灵活方便!如果你想进一步研究JDOM,请到官方网站去看一看:http://www.jdom.org

        本节示例源码:
    package com.cyberobject.study;

    import java.io.IOException;

    import org.jdom.Attribute;
    import org.jdom.Content;
    import org.jdom.Document;
    import org.jdom.Element;
    import org.jdom.output.Format;
    import org.jdom.output.XMLOutputter;

    /**
     * @author kingwong
     *
     * TODO To change the template for this generated type comment go to
     * Window - Preferences - Java - Code Style - Code Templates
     */
    public class TestJDOM {

     public static void main(String[] args)
     {
      Element rootElement = new Element("MyInfo");
      Document myDocument = new Document(rootElement);
     
    //  Attribute rootAttri = new Attribute("comment","introduce myself");
    //  rootElement.setAttribute(rootAttri);
     
      rootElement.setAttribute("comment","introduce myself");
      //rootElement.setAttribute(new Attribute("comment","introduce myself"));
    //  Element sexElement = new Element("sex");
    //  rootElement.addContent(sexElement);
     
    //  Element nameElement = new Element("name");
    //  nameElement.addContent("kingwong");
    //  rootElement.addContent(nameElement);
     
      rootElement.addContent((Content)(new Element("name").addContent("kingwong")));
      rootElement.addContent(new Element("sex").setAttribute("value","male"));
      rootElement.addContent((Content)(new Element("contract").addContent((Content)(new Element("telephone").addContent("87654321")))));
     
      rootElement.removeChild("sex");
     
      XMLOutputter xmlOut = new XMLOutputter(Format.getPrettyFormat());
      try {
       xmlOut.output(myDocument,System.out);
       //xmlOut.output(rootElement.getChild("name"),System.out);
       //String outString = xmlOut.outputString(myDocument);
      } catch (IOException e) {
       e.printStackTrace();
      }
     }
    }

           
    二、XML文档解析
        JDOM 不光可以很方便的建立XML文档,它的另一个用处是它能够读取并操作现有的 XML 数据。
        JDOM的解析器在org.jdom.input.*这个包里,其中的DOMBuilder的功能是将DOM模型的Document解析成JDOM模型的Document;SAXBuilder的功能是从文件或流中解析出符合JDOM模型的XML树。由于我们经常要从一个文件里读取数据,因此我们应该采用后者作为解析工具。
    解析一个xml文档,基本可以看成以下几个步骤:
        1.实例化一个合适的解析器对象
            本例中我们使用SAXBuilder:
            SAXBuilder sb = new SAXBuilder();
        2.以包含XML数据的文件为参数,构建一个文档对象myDocument
            Document myDocument = sb.build(/some/directory/myFile.xml);
        3.获到根元素
            Element rootElement = myDocument.getRootElement();
           
            一旦你获取了根元素,你就可以很方便地对它下面的子元素进行操作了,下面对Element对象的一些常用方法作一下简单说明:
            getChild("childname") 返回指定名字的子节点,如果同一级有多个同名子节点,则只返回第一个;如果没有返回null值。
            getChildren("childname") 返回指定名字的子节点List集合。这样你就可以遍历所有的同一级同名子节点。
            getAttributeValue("name") 返回指定属性名字的值。如果没有该属性则返回null,有该属性但是值为空,则返回空字符串。
            getChildText("childname") 返回指定子节点的内容文本值。
            getText() 返回该元素的内容文本值。
           
            还有其他没有罗列出来的方法,如果需要的话,可以随时查阅JDOM的在线文档:http://www.jdom.org/docs/apidocs/index.html。当然你可以在你需要的地方添加、删除元素操作,还记得上面的创建XML的方法吗?呵呵~~~
           
            学习新东东还是从实例学起最为快捷,下面简单举个例子,就以上面的XML样本代码来学习JDOM的XML解析。本例中读取了样本XML文件里一些属性和content,最后我们还在contact元素里插入了一个新元素<email value="wanghua@cyberobject.com" />。尽管我们实现了对于XML的基本操作,细心的朋友可能会
    有疑问:如果XML文档的层次稍微复杂一些,如果嵌套多达几十上百层的话(开个玩笑),如果靠这样从根元素一级一级地通过getChild("childname")来访问子元素的话,将会非常痛苦!是的,的确是这样,但是我们有另一个有力的工具XPath,为什么不用呢?这是后话!先卖个关子(手敲累啦,下回吧,呵呵)。
           
    /*
     * Created on 2004-8-21
     *
     * TODO To change the template for this generated file go to
     * Window - Preferences - Java - Code Style - Code Templates
     */
    package com.cyberobject.study;

    import org.jdom.Document;
    import org.jdom.Element;
    import org.jdom.input.SAXBuilder;
    import org.jdom.output.Format;
    import org.jdom.output.XMLOutputter;

    /**
     * @author kingwong
     *
     * TODO To change the template for this generated type comment go to
     * Window - Preferences - Java - Code Style - Code Templates
     */
    public class TestJDOM2 {
     public static void main(String[] args){
     SAXBuilder sb = new SAXBuilder();
        try
        {       
         Document doc = sb.build("myFile.xml");
      Element root = doc.getRootElement();
     
      String str1 = root.getAttributeValue("comment");
      System.out.println("Root Element's comment attribute is : " + str1);
      String str2 = root.getChild("sex").getAttributeValue("value");
      System.out.println("sex Element's value attribute is : " + str2);
      String str3 = root.getChildText("name");
      System.out.println("name Element's content is :" + str3);
      String str4 = root.getChild("contact").getChildText("telephone");
      System.out.println("contact Element's telephone subelement content is : " + str4 + "\n");
      Element inputElement = root.getChild("contact");
      inputElement.addContent(new Element("email").setAttribute("value","wanghua@cyberobject.com"));
     
      XMLOutputter xmlOut = new XMLOutputter(Format.getPrettyFormat());
         String outStr = xmlOut.outputString(root);
         System.out.println(outStr);
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }
    }

     
     
    使用DOM方式,Java解析XML基本步骤:
    首先,我们需要建立一个解析器工厂。
    DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();
    然后可以利用这个工厂来获得一个具体的解析对象。
    DocumentBuilder builder=dbf.newDocumentBuilder();
    DocumentBuilder的Parse()方法接受一个XML文档名作为输入参数,返回一个Document对象。Document对象代表了 一个XML文档的树模型。
    Document doc=builder.parse("candiate.xml");
    使用Document对象的getElementsByTagName()方法,我们可以得到一个NodeList对象,他是XML文档中的标签元素 列表,可以使用NodeList对象的item()方法来得列表中的每一个Node对象。
    NodeList nl=doc.getElementsByTagName("PERSON");
    Element node=(Element)nl.item(i);
    最后,我们会使用Node对象的getNodeValue()方法提取某个标签内的内容。
    node.getElementsByTagName("NAME").item(0).getFirstChild().getNodeValue()
    完整程序代码:
    import javax.xml.parsers.*;
    import org.w3c.dom.*;

    public class dom {
    public static void main(String args[]){
    String uri=args[0];
    try{
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();//建立一个解析器工厂。
    DocumentBuilder builder=factory.newDocumentBuilder();//获得一个具体的解析对象。
    Document doc=builder.parse(uri);//返回一个Document对象。
    System.out.println(doc.getImplementation());
    NodeList nl =doc.getElementsByTagName("PERSON");//得到一个NodeList对象。
    for (int i=0;i<nl.getLength();i++){
    Element node=(Element) nl.item(i);//得列表中的每一个Node对象。
    System.out.print("NAME: ");
    System.out.println (node.getElementsByTagName("NAME").item(0).getFirstChild().getNodeValue());
    System.out.print("ADDRESS: ");
    System.out.println (node.getElementsByTagName("ADDRESS").item(0).getFirstChild().getNodeValue());
    System.out.print("TEL: ");
    System.out.println (node.getElementsByTagName("TEL").item(0).getFirstChild().getNodeValue());
    System.out.print("FAX: ");
    System.out.println (node.getElementsByTagName("FAX").item(0).getFirstChild().getNodeValue());
    System.out.print("EMAIL: ");
    System.out.println (node.getElementsByTagName("EMAIL").item(0).getFirstChild().getNodeValue());
    System.out.println();
    }
    }catch(Exception e){
    e.printStackTrace();
    }
    }
    }


    附将数据库表转成XML文件代码:
     

    表tmpinfo字段(id,username,password,sex,officephone,mobile,homephone,corpaddress,homeaddress) 


    public class ExtraTableToXML
    {
     public void BuildXMLDoc()
     {
      Connection conn = null;
      ResultSet rst = null;
      Statement stmt = null;
      try
      {
       conn = ConnectionFactory.getInstance().getConnection();
       stmt = conn.createStatement();
       rst = stmt.executeQuery("select * from tmpinfo");
      }
      catch (Exception sqlException)
      {
       System.out.println("数据库操作错误");
      }
      try
      {
       Document document = new Document(new Element("AllUserInfo"));
       ResultSetMetaData rsmd = rst.getMetaData();      //取得字段名
       String colName = "";
       int i = 0;
       int numOfColumns = rsmd.getColumnCount();
       while (rst.next())
       {
        Element element0 = new Element("userinfo");
        document.getDocument().getRootElement().addContent(element0);
        Element element1 = new Element("phone");
        element0.addContent(element1);
        Element element2 = new Element("address");
        element0.addContent(element2);
        for (i = 1; i < numOfColumns; i++)
        {
         colName = rst.getString(i);
         if (i > 4 && i < 8)
         {
          Element element = new Element(rsmd.getColumnName(i))
            .setText(colName);
          element1.addContent(element);
         }
         else if (i > 7 && i < 9)
         {
          Element element = new Element(rsmd.getColumnName(i))
            .setText(colName);
          element2.addContent(element);
         }
         else
         {
          Element element = new Element(rsmd.getColumnName(i)).setText(colName);
          element0.addContent(element);
         }
        }
        XMLOutputter outp = new XMLOutputter(Format.getPrettyFormat());
        outp.output(document, new FileOutputStream("c:\\userinfo.xml"));
       }
      }
      catch (Exception e)
      {
       System.out.println("XML文档生成错误!");
      }
      
     }
    }


    读取XML文件插入数据库表,表同上述,即tmpinfo

    public void ReadXMLToTable()
     {
      try
      {
       //从文件或流中解析出符合JDom模型的XML树
       SAXBuilder sb = new SAXBuilder();
       
       //构建一个文档对象
       Document doc = sb.build("c:\\userinfo.xml");
       
       //获得根元素
       Element rootElement = doc.getRootElement();
       
       String id="",username="",password="";
       String sex="",officephone="",mobile="";
       String homephone="",corpaddress="",homeaddress="";
       
       Element element = null;
       Element element1 = null;
       Element element2 = null;
       
       List list = null;
       List list1 = null;
       List list2 = null;
       
       //获得指定名字的子节点List集合
       list = rootElement.getChildren("userinfo");
       
       for(int i=0;i<list.size();i++)
       {
        //userinfo节点子元素
        element = (Element)list.get(i);
        
        id=element.getChildText("id");
        username=element.getChildText("username");
        password=element.getChildText("password");
        sex=element.getChildText("sex");
        
        //phone子节点List集合
        list1 = element.getChildren("phone");
        for(int j=0;j<list1.size();j++)
        {
         //phone子节点元素
         element1 = (Element)list1.get(j);
         
         officephone = element1.getChildText("officephone");
         mobile = element1.getChildText("mobile");
         homephone = element1.getChildText("homephone");
        }
        
        //address子节点List集合
        list2 = element.getChildren("address");
        for(int k=0;k<list2.size();k++)
        {
         //address子节点元素
         element2 = (Element)list2.get(k);
         
         corpaddress = element2.getChildText("corpaddress");
         homeaddress = element2.getChildText("homeaddress");
        }
        
        //调用数据DAO类进行插入数据
        Connection conn = ConnectionFactory.getInstance().getConnection();
        PreparedStatement pstmt = null;
        try
        {
         pstmt = conn.prepareStatement("insert into tmpinfo(username,password,sex,officephone,mobile,homephone,corpaddress,homeaddress) values(?,?,?,?,?,?,?,?)");
         pstmt.setString(1,username);
         pstmt.setString(2,password);
         pstmt.setString(3,sex);
         pstmt.setString(4,officephone);
         pstmt.setString(5,mobile);
         pstmt.setString(6,homephone);
         pstmt.setString(7,corpaddress);
         pstmt.setString(8,homeaddress);
         
         pstmt.execute();
        }
        catch (SQLException e)
        {
         // TODO Auto-generated catch block
         e.printStackTrace();
        }
        finally
        {
         try
         {
          pstmt.close();
          conn.close();
         }
         catch (SQLException e)
         {
          // TODO Auto-generated catch block
          e.printStackTrace();
         }
        }
        
        
       }//for
      }
      catch (JDOMException e)
      {
       // TODO Auto-generated catch block
       e.printStackTrace();
      }
      catch (IOException e)
      {
       // TODO Auto-generated catch block
       e.printStackTrace();
      }
     }
  • 相关阅读:
    leetcode Super Ugly Number
    leetcode Find Median from Data Stream
    leetcode Remove Invalid Parentheses
    leetcode Range Sum Query
    leetcode Range Sum Query
    leetcode Minimum Height Trees
    hdu 3836 Equivalent Sets
    hdu 1269 迷宫城堡
    hud 2586 How far away ?
    poj 1330 Nearest Common Ancestors
  • 原文地址:https://www.cnblogs.com/kentyshang/p/820782.html
Copyright © 2011-2022 走看看