<?xml version="1.0" encoding="UTF-8" standalone="no"?> <cars> <car id="1"> <name>bus</name> <effect>城市公共交通工具</effect> <weight>3</weight> <fixed>40</fixed> </car> <car id="2"> <name>tractor</name> <effect>农业运载工具</effect> <weight>2</weight> <fixed>2</fixed> </car> </cars>
现有如上XML文档,请使用DOM为id为1的汽车添加长度元素(length),同时修改fixed元素的值为30,并将id为2的汽车fixed元素删除。
View Code
1 package com.yiscat.dom; 2 3 import java.io.File; 4 import java.io.FileInputStream; 5 import java.io.IOException; 6 import java.io.StringWriter; 7 8 import javax.xml.parsers.DocumentBuilder; 9 import javax.xml.parsers.DocumentBuilderFactory; 10 import javax.xml.parsers.ParserConfigurationException; 11 import javax.xml.transform.OutputKeys; 12 import javax.xml.transform.Transformer; 13 import javax.xml.transform.TransformerConfigurationException; 14 import javax.xml.transform.TransformerException; 15 import javax.xml.transform.TransformerFactory; 16 import javax.xml.transform.dom.DOMSource; 17 import javax.xml.transform.stream.StreamResult; 18 19 import org.apache.xml.serialize.OutputFormat; 20 import org.apache.xml.serialize.XMLSerializer; 21 import org.w3c.dom.Document; 22 import org.w3c.dom.Element; 23 import org.w3c.dom.NamedNodeMap; 24 import org.w3c.dom.Node; 25 import org.w3c.dom.NodeList; 26 import org.xml.sax.SAXException; 27 28 public class DOMForXML { 29 30 public static Document doc = getDocuemt("car.xml"); 31 public static int count = 0; 32 33 /** 34 * 获取document对象 35 * 36 * @param fileName 37 * xml文件路径 38 * @return 39 */ 40 public static Document getDocuemt(String filePath) { 41 42 // 通过DOM解析器解析XML文件 43 // DOMParser parser = new DOMParser(); 44 // try { 45 // parser.parse("car.xml"); 46 // Document document = parser.getDocument(); 47 // } catch (SAXException e) { 48 // // TODO Auto-generated catch block 49 // e.printStackTrace(); 50 // } catch (IOException e) { 51 // // TODO Auto-generated catch block 52 // e.printStackTrace(); 53 // } 54 55 // 使用JAPX的工厂方法获得解析器对象 56 Document document = null; 57 // 获取DecumentBuilderFactory类的对象 58 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 59 DocumentBuilder builder; 60 try { 61 // 获取DocumentBuilder类的对象 62 builder = factory.newDocumentBuilder(); 63 // 获取Document对象 64 document = builder.parse(new FileInputStream(filePath)); 65 } catch (ParserConfigurationException e) { 66 // TODO Auto-generated catch block 67 e.printStackTrace(); 68 } catch (SAXException e) { 69 // TODO Auto-generated catch block 70 e.printStackTrace(); 71 } catch (IOException e) { 72 // TODO Auto-generated catch block 73 e.printStackTrace(); 74 } 75 return document; 76 } 77 78 /** 79 * 更新源文件 80 * 81 * @param document 82 * 文档节点 83 * @param filePath 84 * xml文件路径 85 * @return 86 */ 87 public static boolean saveXML(Document document, String filePath) { 88 boolean flag = false; 89 // 输出文档到文件中 90 TransformerFactory factory = TransformerFactory.newInstance(); 91 try { 92 // 使用工厂模式,实例化Transformer 93 Transformer transformer = factory.newTransformer(); 94 transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); // 处理中文的 95 // 由DOM充当源树, 源树包含了源(如xml源)输入信息, 准备输出文档 96 DOMSource source = new DOMSource(document); 97 // 实例化结果树,结果树指转换后(对于stremResult包含了结果的输出流)结果的持有者 98 StreamResult result = new StreamResult(new File(filePath)); 99 // Transformer能够将源树转换成结果树 100 transformer.transform(source, result); 101 flag = true; 102 } catch (TransformerConfigurationException e) { 103 // TODO Auto-generated catch block 104 e.printStackTrace(); 105 } catch (TransformerException e) { 106 // TODO Auto-generated catch block 107 e.printStackTrace(); 108 } 109 return flag; 110 } 111 112 /** 113 * 在控制台输出xml文件 114 * 115 * @param document 116 * 文档节点 117 * @return 118 */ 119 public static boolean pritlnXML(Document document) { 120 boolean flag = false; 121 try { 122 // 输出一个DOM序列化的字符串 123 OutputFormat format = new OutputFormat(document); // 格式化DOM 124 StringWriter stringOut = new StringWriter(); // 字符流 125 XMLSerializer serial = new XMLSerializer(stringOut, format); 126 serial.asDOMSerializer(); // DOM序列化 127 serial.serialize(document.getDocumentElement()); 128 // 输出一个String的DOM 129 System.out.println(stringOut.toString()); 130 } catch (Exception ex) { 131 ex.printStackTrace(); 132 } 133 return flag; 134 } 135 136 /** 137 * 遍历文档 138 * 139 * @param node 140 */ 141 public static void processNode(Node node) { 142 switch (node.getNodeType()) { 143 // case Node.TEXT_NODE: 144 // 处理文本节点 145 // DOM中换行及空格也是作为节点处理的,这里把XML文件中的换行和空格过滤掉 146 // if (!node.getNodeValue().trim().equals("")) { 147 // System.out.println("元素数据:" + node.getNodeValue()); 148 // } 149 // break; 150 case Node.ELEMENT_NODE: 151 // 处理元素的属性 152 if (node.hasAttributes()) { 153 NamedNodeMap map = node.getAttributes(); 154 for (int i = 0; i < map.getLength(); i++) { 155 count++; 156 if (count == 1) { 157 Node lengthNode = doc.createElement("length"); // 创建length节点 158 lengthNode.appendChild(doc.createTextNode("长度")); // 设置节点内容 159 node.appendChild(lengthNode); // 设置节点关系 160 } 161 } 162 } 163 164 // 处理元素节点 165 if (node.getNodeName().equalsIgnoreCase("fixed")) { // 判断是否为fixed元素 166 if (count == 1) { 167 node.getFirstChild().setNodeValue("30"); // 设置fixed节点内容 168 } 169 if (count == 2) { 170 Node parent = node.getParentNode(); // 获取fixed元素的父节点 171 parent.removeChild(node); // 移除fixed元素节点 172 } 173 } 174 175 // 处理元素的子元素 176 if (node.hasChildNodes()) { 177 NodeList childNodeList = node.getChildNodes(); 178 for (int i = 0; i < childNodeList.getLength(); i++) { 179 Node childNode = childNodeList.item(i); 180 // 递归调用 181 processNode(childNode); 182 } 183 } 184 break; 185 } 186 } 187 188 public static void main(String[] args) { 189 // 获取根元素 190 Element root = doc.getDocumentElement(); 191 192 // 调用自定义静态方法对根元素进行处理 193 processNode(root); 194 195 // 控制台输出 196 pritlnXML(doc); 197 198 // 更改源文件 199 saveXML(doc, "car.xml"); 200 } 201 }
以上代码中,需要导入jar包:xerces-2.6.2.jar,由于之前导入的是xerces-2.3.0.jar包,遇到 java.lang.AbstractMethodError: org.apache.crimson.tree.XmlDocument.getXmlStandalone()Z
报错,换成xerces-2.6.2.jar就可以了!
原先还有导入crimson.jar包,但也是报这个错误,后来查到是sun把crimson.jar给废了,可是又没有错误提示。把crimson.jar删除了,xml就可以正常生成了。
Exception in thread "main" java.lang.AbstractMethodError: org.apache.crimson.tree.XmlDocument.getXmlStandalone()Z at com.sun.org.apache.xalan.internal.xsltc.trax.DOM2TO.setDocumentInfo(DOM2TO.java:373) at com.sun.org.apache.xalan.internal.xsltc.trax.DOM2TO.parse(DOM2TO.java:127) at com.sun.org.apache.xalan.internal.xsltc.trax.DOM2TO.parse(DOM2TO.java:94) at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transformIdentity(TransformerImpl.java:662) at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:708) at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:313)
在控制台和源文件car.xml输出如下: