package com.linzl.cn.xml;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
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.CDATASection;
import org.w3c.dom.Comment;
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.InputSource;
import org.xml.sax.SAXException;
/**
* w3c xml 例子 详细方法可见JDK1.6的API 文档驱动: 缺点: 在处理DOM的时候,我们需要读入整个的XML文档, 然后在内存中创建DOM树,
* 当xml非常大的时候,很消耗内存 超过10M不适用 优点: 形成树结构,代码易编写;解析过程树结构在内存中,方便修改
*
* @author linzl 最后修改时间:2014年10月10日
*/
public class DomUtils {
/**
* 创建DocumentBuilder
*
* @return
* @throws ParserConfigurationException
*/
private static DocumentBuilder createBuilder()
throws ParserConfigurationException {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true); // never forget this!
DocumentBuilder builder = factory.newDocumentBuilder();
return builder;
}
/**
* 使用JDK自带的类转换Document对象转成字符串
*
* @param doc
* @return
* @throws TransformerException
*/
public static String docToString(Document doc) throws TransformerException {
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
// 设置编码
transformer
.setOutputProperty(OutputKeys.ENCODING, doc.getXmlEncoding());
// 设置格式换行
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
ByteArrayOutputStream bos = new ByteArrayOutputStream();
transformer.transform(new DOMSource(doc), new StreamResult(bos));
return bos.toString();
}
/**
* xml文件转Document
*
* @param file
* @return
* @throws SAXException
* @throws IOException
* @throws ParserConfigurationException
*/
public static Document fileToDoc(File file)
throws ParserConfigurationException, SAXException, IOException {
// 创建DocumentBuilder
DocumentBuilder builder = createBuilder();
// 创建Document
Document doc = builder.parse(file);
doc.normalize();
return doc;
}
/**
* xml文件转Document
*
* @param is
* @return
* @throws SAXException
* @throws IOException
* @throws ParserConfigurationException
*/
public static Document fileToDoc(InputStream is)
throws ParserConfigurationException, SAXException, IOException {
// 创建DocumentBuilder
DocumentBuilder builder = createBuilder();
// 创建Document
Document doc = builder.parse(is);
doc.normalize();
return doc;
}
/**
* 字符串内容转换成Document对象
*
* @param xmlStr
* @return
* @throws ParserConfigurationException
* @throws SAXException
* @throws IOException
*/
public static Document stringToDoc(String xmlStr)
throws ParserConfigurationException, SAXException, IOException {
DocumentBuilder builder = createBuilder();
StringReader sr = new StringReader(xmlStr);
InputSource is = new InputSource(sr);
Document doc = builder.parse(is);
doc.normalize();
return doc;
}
/**
* 将Document格式化到目标文件
*
* @param doc
* @param targetFile
* @throws IOException
* @throws TransformerException
*/
public static void formatToXMLFile(Document doc, File targetFile)
throws TransformerException, IOException {
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
// 设置编码
transformer
.setOutputProperty(OutputKeys.ENCODING, doc.getXmlEncoding());
// 设置格式换行
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
ByteArrayOutputStream bos = new ByteArrayOutputStream();
transformer.transform(new DOMSource(doc), new StreamResult(bos));
// 将xmlStr输出到目标路径,使用xml文件的头文件编码
FileOutputStream fos = new FileOutputStream(targetFile);
bos.writeTo(fos);
}
/**
* 将xmlStr格式化到目标文件
*
* @param xmlStr
* @param targetFile
* @throws ParserConfigurationException
* @throws SAXException
* @throws IOException
* @throws TransformerException
*/
public static void formatToXMLFile(String xmlStr, File targetFile)
throws ParserConfigurationException, SAXException, IOException,
TransformerException {
Document doc = stringToDoc(xmlStr);
formatToXMLFile(doc, targetFile);
}
/**
* 将xml文件格式化到目标文件
*
* @param srcFile
* xml源文件
* @param targetFile
* 格式化输出xml文件
* @throws TransformerException
* @throws IOException
* @throws SAXException
* @throws ParserConfigurationException
*/
public static void formatToXMLFile(File srcFile, File targetFile)
throws TransformerException, ParserConfigurationException,
SAXException, IOException {
Document doc = fileToDoc(srcFile);
formatToXMLFile(doc, targetFile);
}
/**
* 打印Document的结点基本信息
*
* @param doc
*/
public static void printNode(Document doc) {
Element root = doc.getDocumentElement();
printRecursive(root);
}
/**
* 递归打印结点信息
*
* @param element
*/
private static void printRecursive(Node element) {
int length = 0;
Node node = null;
NamedNodeMap nnm = element.getAttributes();
if (nnm != null || (length = nnm.getLength()) > 0) {
for (int attrIndex = 0; attrIndex < length; attrIndex++) {
node = nnm.item(attrIndex);
System.err.println("属性名称:" + node.getNodeName() + " -->属性值:"
+ node.getNodeValue());
}
}
// NodeList nodeList = element.getElementsByTagName("exoa-config");
NodeList nodeList = element.getChildNodes();
if (nodeList != null && (length = nodeList.getLength()) > 0) {
for (int index = 0; index < length; index++) {
node = nodeList.item(index);
// dom会将换行和注释都做为document的结点,所以去除这些非element结点
if (node != null && node.getNodeType() != Node.ELEMENT_NODE) {
continue;
}
System.err.println("结点名称 -->" + node.getNodeName().trim());
// getTextContent将所有该结点下所有结点的纯文本值
System.err.println("结点下所有结点的值 -->"
+ node.getTextContent().trim());
// 当该结点下只有一个文本结点时,效果等同getTextContent,否则根据JDK中对于Node的解释,getNodeValue是取不到值的
Node child = node.getFirstChild();
if (child != null) {
System.err.println("结点值 -->" + child.getNodeValue().trim());
}
printRecursive(node);
}
}
}
/**
* w3c Dom的生成: 直接按照从上到下的结点顺序创建,然后append在父结点下
*
* @throws ParserConfigurationException
* @throws TransformerException
*/
public static void createDocXML() throws ParserConfigurationException,
TransformerException {
Document doc = createBuilder().newDocument();
doc.setXmlStandalone(true);
// 根结点
Element root = doc.createElement("root");
// 注释内容
Comment comment = doc.createComment("根结点注释");
root.appendChild(comment);
// 生成第一个孩子结点
Element rootChildA = doc.createElement("rootChildA");
rootChildA.setTextContent("rootChildA孩子结点");
rootChildA.setAttribute("name", "姓名");
rootChildA.setAttribute("age", "年龄");
rootChildA.setAttribute("height", "身高");
root.appendChild(rootChildA);
Element rootChildB = doc.createElement("rootChildB");
CDATASection cdata = doc.createCDATASection("rootChildB孩子结点");
rootChildB.appendChild(cdata);
root.appendChild(rootChildB);
doc.appendChild(root);
// 规范xml文件,并输出到目标文件
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
// 设置格式换行
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
DOMSource dos = new DOMSource(doc);
File file = new File("D://w3c.xml");
StreamResult result = new StreamResult(file);
transformer.transform(dos, result);
}
public boolean removeNode() {
return true;
}
public boolean updateNode() {
return true;
}
public static void main(String[] args) throws Exception {
// InputStream is = DomUtils.class
// .getResourceAsStream("/com/linzl/cn/xml/xmlRead.xml");
//
// is = DomUtils.class.getClassLoader().getResourceAsStream(
// "com/linzl/cn/xml/xmlRead.xml");
// is = new
// FileInputStream("F:\\anjianOAdoc\\oadoc\\taitan\\info\\757.xml");
// Document doc = fileToDoc(is);
// printNode(doc);
// createDocXML();
String xmlStr = "F:\\anjianOAdoc\\oadoc\\taitan\\info\\757.xml";
String target = "F:\\anjianOAdoc\\oadoc\\taitan\\missive\\757-副本.xml";
formatToXMLFile(new File(xmlStr), new File(target));
}
}