用DOM对xml文件的一些操作

来源:互联网 发布:unity3d 对话框 编辑:程序博客网 时间:2024/05/22 06:52

刚上班,公司还没给安排什么事情,闲着没事就看看xml

下面是使用DOM对xml文件的一些操作:

 

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
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.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class OrderProcessor{
 public static void main(String args[]){
  //创建orders.xml文件
  File docFile=new File("orders.xml");
  //声明Document对象
  Document doc=null;
  Document newdoc=null;//用于创建新的xml对象
//  try{
//   DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();
//   DocumentBuilder db=dbf.newDocumentBuilder();
//   doc=db.parse(docFile);
//  }catch(Exception e){
//   System.out.println("Problem parsing the file:"+e.getMessage());
//  }
   
  try {
   DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();
   DocumentBuilder db = dbf.newDocumentBuilder();
   doc=db.parse(docFile);
   newdoc=db.newDocument();
  } catch (ParserConfigurationException e) {
   // TODO Auto-generated catch block
   System.out.println("The parser was not configured correctly");
   e.printStackTrace();
  } catch (SAXException e) {
   // TODO Auto-generated catch block
   System.out.println("problem parsing the file");
   e.printStackTrace();
  } catch (IOException e) {
   // TODO Auto-generated catch block
   System.out.println("can not read input file");
   e.printStackTrace();
  }
  //获得文档根节点
  Element root=doc.getDocumentElement();
  System.out.println("The root element is : "+root.getNodeName());
  //获得根节点下节点数,包括节点间的空白节点
  NodeList children=root.getChildNodes();
  System.out.println("There are "+children.getLength()+" nodes in the document");
  //遍历每个节点:名字和对应的值
  for(Node child=root.getFirstChild();child!=null;child=child.getNextSibling()){
   System.out.println(child.getNodeName()+"="+child.getNodeValue());
  } 
  stepThrough(root);//遍历整个文档树
  stepThroughAll(root);//递归遍历整个文档树包括节点的属性
  changOrder(root,"status","processing");//更改所有status节点的值为processing
  //检测所有的status节点的值是否修改
  NodeList orders=root.getElementsByTagName("status");
  for(int orderNum=0;orderNum<orders.getLength();orderNum++){
   System.out.println(orders.item(orderNum).getFirstChild().getNodeValue());
  }
  NodeList ordersPrice=root.getElementsByTagName("order");
  for(int orderNum=0;orderNum<ordersPrice.getLength();orderNum++){
   Element thisOrder=(Element)ordersPrice.item(orderNum);
   //删除节点属性
   Element customer=(Element)thisOrder.getElementsByTagName("customerid").item(0);
   customer.removeAttribute("limit");
   //获取每个Item的总价格
   NodeList orderItems=thisOrder.getElementsByTagName("item");
   double total=0;
   for(int itemNum=0;itemNum<orderItems.getLength();itemNum++){
    //Get this item as an element
    Element thisOrderItem=(Element)orderItems.item(itemNum);
    //删除节点
    if(thisOrderItem.getAttributeNode("instock").getNodeValue().equals("N")){
     Node deadNode=thisOrderItem.getParentNode().removeChild(thisOrderItem);
    }else if(thisOrderItem.getAttributeNode("instock").getNodeValue().equals("N")){
     //新增节点属性
     Element backElement=doc.createElement("backordered");
     backElement.setAttributeNode(doc.createAttribute("itemid"));
     String itemIdString=thisOrderItem.getAttributeNode("itemid").getNodeValue();
     backElement.setAttribute("itemid", itemIdString);
     //替换节点
     Node deadNode=thisOrderItem.getParentNode().replaceChild(backElement, thisOrderItem);
    }else{
     //Get pricing information for this Item
     String thisPrice=thisOrderItem.getElementsByTagName("price").item(0).getFirstChild().getNodeValue();
     double thisPriceDbl=new Double(thisPrice).doubleValue();
     //Get quantity information for this Item
     String thisQty=thisOrderItem.getElementsByTagName("qty").item(0).getFirstChild().getNodeValue();
     double thisQtyDbl=new Double(thisQty).doubleValue();
     double thisItemTotal=thisPriceDbl*thisQtyDbl;
     total=total+thisItemTotal;
    }
   }
   //新增Item总价格节点
   String totalString=new Double(total).toString();
   Node totalNode=doc.createTextNode(totalString);
   Element totalElement=doc.createElement("total");
   totalElement.appendChild(totalNode);
   thisOrder.insertBefore(totalElement, thisOrder.getFirstChild());
  }
  //建立新的xml文档
  Element newRoot=newdoc.createElement("processedOrders");
  NodeList processOrders=doc.getElementsByTagName("order");
  for(int orderNum=0;orderNum<processOrders.getLength();orderNum++){
   Element thisOrder=(Element)processOrders.item(orderNum);
   Element customerid=(Element)thisOrder.getElementsByTagName("customerid").item(0);
   String limit=customerid.getAttributeNode("limit").getNodeValue();
   String total=thisOrder.getElementsByTagName("total").item(0).getFirstChild().getNodeValue();
   double limitDbl=new Double(limit).doubleValue();
   double totalDbl=new Double(total).doubleValue();
   Element newOrder=newdoc.createElement("order");
   Element newStatus=newdoc.createElement("status");
   if(totalDbl>limitDbl){
    newStatus.appendChild(newdoc.createTextNode("REJECTED"));
   }else{
    newStatus.appendChild(newdoc.createTextNode("PROCESSED"));
   }
   Element newCustomer=newdoc.createElement("customerid");
   String oldCustomer=customerid.getFirstChild().getNodeValue();
   newCustomer.appendChild(newdoc.createTextNode(oldCustomer));
   Element newTotal=newdoc.createElement("total");
   newTotal.appendChild(newdoc.createTextNode(total));
   newOrder.appendChild(newStatus);
   newOrder.appendChild(newCustomer);
   newOrder.appendChild(newTotal);
   newRoot.appendChild(newOrder);
  }
  newdoc.appendChild(newRoot);
  //序列化xml文档
  //恒等转换
  try {
   DOMSource source=new DOMSource(newdoc);
   StreamResult result=new StreamResult(new FileOutputStream("processed.xml"));
   TransformerFactory transFactory=TransformerFactory.newInstance();
   Transformer transformer=transFactory.newTransformer();
   transformer.transform(source, result);
  } catch (FileNotFoundException e1) {
   // TODO Auto-generated catch block
   e1.printStackTrace();
  } catch (TransformerConfigurationException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (TransformerException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
  
  System.out.print(newRoot.toString());
  //创建新的processedOrders.xml文件
  try {
   File newFile=new File("processedOrders.xml");
   FileWriter newFileStream=new FileWriter(newFile);
   newFileStream.write("<?xml version=/"1.0/"?>");
   newFileStream.write("<!DOCTYPE>"+doc.getDoctype().getName()+" ");
   if(doc.getDoctype().getSystemId()!=null){
    newFileStream.write(" SYSTEM ");
    newFileStream.write(doc.getDoctype().getSystemId());
   }
   if(doc.getDoctype().getPublicId()!=null){
    newFileStream.write(" PUBLIC ");
    newFileStream.write(doc.getDoctype().getPublicId());
   }
   newFileStream.write(">");
   newFileStream.write(newRoot.toString());
   newFileStream.close();
  } catch (IOException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
   System.out.println("Can't write new file.");
  }
  
  stepThrough(root);
 }
 //递归遍历整个文档树
 private static void stepThrough(Node start){
  System.out.println(start.getNodeName()+"="+start.getNodeValue());
  for(Node child=start.getFirstChild();child!=null;child=child.getNextSibling()){
   stepThrough(child);
  }
 }
 //递归遍历整个文档树包括节点的属性
 private static void stepThroughAll(Node start){
  System.out.println(start.getNodeName()+"="+start.getNodeValue());
  if(start.getNodeType()==start.ELEMENT_NODE){
   NamedNodeMap startAttr=start.getAttributes();
   for(int i=0;i<startAttr.getLength();i++){
    Node attr=startAttr.item(i);
    System.out.println("Attribute:"+attr.getNodeName()+"="+attr.getNodeValue());
   }   
  }
  for(Node child=start.getFirstChild();child!=null;child=child.getNextSibling()){
   stepThroughAll(child);
  }
 }
 //递归更改某个节点的值。start根节点,elemName元素名,elemValue新元素值
 private static void changOrder(Node start,String elemName,String elemValue){
  if(start.getNodeName().equals(elemName)){
   start.getFirstChild().setNodeValue(elemValue);
  }
  for(Node child=start.getFirstChild();child!=null;child=child.getNextSibling()){
   changOrder(child,elemName,elemValue);
  }
 }
}

ultredit编辑的xml文件会抛出"Content is not allowed in prolog"异常。上网查,说可能是BOM问题,说很多编辑器保存UTF-8时会在前面加个0xFE之类的,但是很多XML解析器又不认识。原来无BOM头的UTF-8文件在经过UltraEdit编辑后, UltraEdit会擅自作主添加一个BOM(EditPlus无此问题, 记事本似乎有此问题), 即使去掉UltraEdit中与BOM

关的所有设置选项也无济于事。不过好的一点的是我用eclipse就没问题了。