打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
用DOM/JDOM解析XML文件

   夜已经深了,可是我仍未眠。明天就要回家过年了,对于一个飘荡在外的游子来说,回家过年是一件多么激动人心的事啊!这才是我心中真正的年啊!
   真希望新的一年快点到来,因为有太多的不愉快需要忘记、因为有太多的梦想需要去实现……

   前一段时间要解析一个XML文件,就是对XML进行增、删、改的操作。以前做J2EE时一直都是用第三方的类库来辅助解决的,但这次却要求自己用DOM来解析,只能用JDK自带的类库!
   一直到现在还没有想通:为什么要重复发明轮子呢???但是事情还是要做的,我只是俗人,我也要吃饭……
   又或许,这只是我的又一个自我解嘲的借口罢了!

  下边的类其实有很多不足的地方的,但我却始终不能说服我自己, 我就是这样一个倔强又刚愎自用的人,期待来年吧,希望走过本命年的我能成熟起来,对于一些事情的控制更自由一些。。。

import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.StringTokenizer;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

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

/**
* <p>ConfigParser</p>
* 1. read the config XML,or update the file.</br>
* 2. query a property from the config file,the property name fromat:lss.agent.version etc.</br>
* 3. add properties into the config file.</br>
*
* <p>@author javer QQ:84831612</p>
*/
public class ConfigParser
{
   private File xmlFile = null;

   private Document doc = null;

   private Element root = null;

   public ConfigParser(String filename)
   {
      xmlFile = new File(filename);
      try
      {
         DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
         doc = builder.parse(xmlFile);
         root = doc.getDocumentElement();
       }
       catch(Exception e)
       {
          System.err.println("Error creating XML parser in ConfigParser.java");
          e.printStackTrace();
       }
   }

   /**
   * Return the value of the specified property.
   *
   * @param name the name of the property to get.
   * @return the value of the specified property.
   */
   public String getValue(String name)
   {
      String[] propName = parsePropertyName(name);
   
      NodeList nodes = root.getElementsByTagName(propName[0]);
      if(nodes == null || nodes.getLength() < 1)
         return null;
      for(int i = 1; i < propName.length; i++)
      {
         nodes = ((Element)nodes.item(0)).getElementsByTagName(propName[i]);
         if(nodes == null || nodes.getLength() < 1)
            return null;
      }
   
      Node node = nodes.item(0).getChildNodes().item(0);
      if(node != null)
         return node.getNodeValue();
      else
         return null;
   }
   
   /**
   * <p>Add the values by the specified properties.</p>
   * For example:</br>
   * if values is existed as follow</br>
   * x.y.z1=1</br>
   *    .z2=2</br>
   *    .z3=3</br>
   * and now, you need add new values as a new group,like as follow values</br>
   * x.y.z1=11</br>
   *    .z2=22</br>
   *    .z3=33</br>
   * you need call this function like as follow:</br>
   * addValue("x.y",new String[]{"z1","z2","z3"},new String[]{"11","22","33"})</br>
   * and the XML will have a result as follow:</br>
   * <xml>
   *    <x>
   *       <y>
   *          <z1>1</z1>
   *          <z2>2</z2>
   *          <z2>3</z2>
   *       </y>
   *       <y>
   *          <z1>11</z1>
   *          <z2>22</z2>
   *          <z2>33</z2>
   *       </y>
   *    </x>
   * </xml>
   *
   * @param parentName
   * @param subNames
   * @param values
   */
   public void addValue(String parentName, String[] subNames, String[] values)
   {
      String[] propName = parsePropertyName(parentName);

      NodeList nodes = root.getElementsByTagName(propName[0]);
      if(nodes == null || nodes.getLength() < 1)
      {
        root.appendChild(doc.createElement(propName[0]));
        nodes = root.getElementsByTagName(propName[0]);
      }
      Element tempElement = ((Element)nodes.item(0));
      for(int i = 1; i < propName.length - 1; i++)
      {
         tempElement = ((Element)nodes.item(0));
         nodes = tempElement.getElementsByTagName(propName[i]);
         if(nodes == null || nodes.getLength() < 1)
         {
            tempElement.appendChild(doc.createElement(propName[i]));
            nodes = tempElement.getElementsByTagName(propName[i]);
         }
      }

      tempElement = (Element)tempElement.appendChild(doc.createElement(propName[propName.length - 1]));
      Node node = null;
      for(int i = 0; i < subNames.length; i++)
      {
         node = tempElement.appendChild(doc.createElement(subNames[i]));
         node.appendChild(doc.createTextNode(values[i]));
      }

      store();
   }

   /**
   * Update the value of the specified property.
   * @param name
   * @param value
   */
   public void updateValue(String name, String value)
   {
      String[] propName = parsePropertyName(name);

      NodeList nodes = root.getElementsByTagName(propName[0]);
      if(nodes == null || nodes.getLength() < 1)
         return;
      for(int i = 1; i < propName.length; i++)
      {
         nodes = ((Element)nodes.item(0)).getElementsByTagName(propName[i]);
         if(nodes == null || nodes.getLength() < 1)
            return;
      }

      Node node = nodes.item(0).getChildNodes().item(0);
      if(node != null)
         node.setNodeValue(value);
      else
         return;

      store();
   }

   /**
   * Deletes the specified property.
   *
   * @param name the property to delete.
   */
   public void deleteProperty(String name)
   {
      String[] propName = parsePropertyName(name);
      if(propName.length == 1)
         root.removeChild(root.getElementsByTagName(propName[0]).item(0));
      else
      {
         NodeList nodes = root.getElementsByTagName(propName[0]);
         for(int i = 1; i < propName.length - 1; i++)
         {
            nodes = ((Element)nodes.item(0)).getElementsByTagName(propName[i]);
            if(nodes == null || nodes.getLength() < 1)
               return;
         }

         nodes.item(0).removeChild(((Element)nodes.item(0)).getElementsByTagName(
         propName[propName.length - 1]).item(0));
      }

      store();
   }

   /**
   * Return all children property names of a parent property as a String array,
   * or an empty array if the if there are no children. For example, given
   * the properties <tt>X.Y.A</tt>, <tt>X.Y.B</tt>, and <tt>X.Y.C</tt>, then
   * the child properties of <tt>X.Y</tt> are <tt>A</tt>, <tt>B</tt>, and
   * <tt>C</tt>.
   *
   * @param parent the name of the parent property.
   * @return all child property values for the given parent.
   */
   public String[] getChildrenProperties(String parent)
   {
      String[] propName = parsePropertyName(parent);
      NodeList nodes = root.getElementsByTagName(propName[0]);
      if(nodes == null || nodes.getLength() < 1)
         return null;
      for(int i = 1; i < propName.length; i++)
      {
         nodes = ((Element)nodes.item(0)).getElementsByTagName(propName[i]);
         if(nodes == null || nodes.getLength() < 1)
            return null;
      }

      nodes = nodes.item(0).getChildNodes();
      ArrayList list = new ArrayList();
      for(int i = 0; i < nodes.getLength(); i++)
      {
         if(nodes.item(i).getNodeType() == Node.ELEMENT_NODE)
            list.add(nodes.item(i).getNodeName());
      }

      if(list == null)
         return null;
      else
         return (String[])list.toArray(new String[list.size()]);
   }

   /**
   * Return the value when the specified property key and value is existent,
   * and return null if the specified property key and value is not existent
   *
   * @param name
   * @param value
   * @return
   */
   public String findValue(String name, String value)
   {
      String[] propName = parsePropertyName(name);
      return findValue(root, 0, propName, value);
   }

   private String findValue(Element element, int depth, String[] propName,String value)
   {
      String _value = null;
      if(depth == propName.length)
      {
         _value = element.getChildNodes().item(0).getNodeValue();
         if(_value.equals(value))
            return value;
         else
            return null;
      }

      NodeList children = element.getElementsByTagName(propName[depth]);
      if(children == null || children.getLength() < 1)
         return null;
      else
         ++depth;

      for(int i = 0; i < children.getLength(); i++)
      {
         if(children.item(i).getNodeType() != Node.ELEMENT_NODE)
            continue;

         element = (Element)children.item(i);
         _value = findValue(element, depth, propName, value);
         if(_value != null)
         {
            return value;
         }
      }

      return null;
   }

// public static void main(String[] args) throws Exception
// {
// System.out.println("Start****************************");
// ConfigParser test = new
// ConfigParser("/test.xml");

// update
// System.out.println(test.getValue("x.y"));
// test.updateValue("x.y","xyz");
// System.out.println(test.getValue("x.y"));

// delete
// System.out.println(test.getValue("x.y"));
// test.deleteProperty("x.y");
// System.out.println(test.getValue("x.y"));

// getChildrenProperties
// String[] childrenNames = test.getChildrenProperties("x.y");
// if(childrenNames!=null)
// for(int i=0;i<childrenNames.length;i++)
// {
// System.out.println("childrenNames["+i+"]=" + childrenNames[i]);
// }

// find
// System.out.println(test.findValue("x.y.z1","cc22"));

// add
// test.addValue("x.y",new String[]{"z1","z2","z3","z4"},new String[]{"11","22","33","44"}
// );
//
// System.out.println("End****************************");
// }

   private synchronized void store()
   {
      boolean error = false;
      File tempFile = new File(xmlFile.getParentFile(), xmlFile.getName() + ".tmp");
      FileOutputStream out = null;
      try
      {
         DOMSource ds = new DOMSource(root);
         out = new FileOutputStream(tempFile);
         StreamResult sr = new StreamResult(out);
         TransformerFactory tff = TransformerFactory.newInstance();
         Transformer tf = tff.newTransformer();
         tf.transform(ds, sr);
      }
      catch(Exception e)
      {
         e.printStackTrace();
         error = true;
      }
      finally
      {
         try
         {
            out.flush();
            out.close();
         }
         catch(Exception e)
         {
            e.printStackTrace();
            error = true;
         }
      }

      if(!error)
      {
         xmlFile.delete();
         tempFile.renameTo(xmlFile);
      }
   }

   private String[] parsePropertyName(String name)
   {
      int size = 1;
      for(int i = 0; i < name.length(); i++)
      {
         if(name.charAt(i) == ‘.‘)
         {
            size++;
         }
      }
      String[] propName = new String[size];
      StringTokenizer tokenizer = new StringTokenizer(name, ".");
      int i = 0;
      while(tokenizer.hasMoreTokens())
      {
         propName[i] = tokenizer.nextToken();
         i++;
      }
      return propName;
   }
}

   既然提到了JDOM,就不得不搞清楚它和DOM的关系,免得被人问及为何选择此种解决方案时再次无言 ;) (具体的理论性质的比较,google、baidu上有一堆堆的说明,这里就不再copy)同样的类,还有一个用JDOM的实现版本,同样多的代码量下,JDOM的容错性、可扩展性似乎更好些。这一页的内容太多,还是放到下一页吧……


本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
配置java才解析xml文件
Android笔试总结
在Jdk1.4的基础上读取Excel2007
Java Dom解析xml
java读XML文件例子
xml文件解析-DOM
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服