• 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();
      }
     }
  • 相关阅读:
    python yaml文件数据按原有的数据顺序dump
    HTMLTestRunner
    os.path获取当前路径及父路径
    update 字符串拼接
    VSCode 快速生成.vue基本模板、发送http请求模板
    Vue取消eslint语法限制
    node-sass安装失败解决方法
    docker 创建mysql和redis
    阿里云镜像加速器地址
    .net core + xunit 集成测试
  • 原文地址:https://www.cnblogs.com/kentyshang/p/820782.html
Copyright © 2020-2023  润新知