JAVA学习笔记 -- 读写XML
XML是一种可扩展标记语言
以下是一个完整的XML文件(也是下文介绍读写XML的样本):
<?xml version="1.0" encoding="UTF-8"?
> <poem author="William Carlos Williams" title="The Great Figure"> <line>Among the rain</line> <line>and ligths</line> <line>I saw the figure 5</line> <line>in gold</line> <line>on a red</line> <line>fire truck</line> <line>moving</line> <line>tense</line> <line>unheeded</line> <line>to gong clangs</line> <line>siren howls</line> <line>and wheels rumbling</line> <line>through the dark city</line> </poem>
一、写XML
本文介绍两种方式:使用DOM开发包来写XML文件和用String对象的方式
将Poem类作为数据源,提供须要转换成XML的内容:
class Poem { private static String title = "The Great Figure"; private static String author = "William Carlos Williams"; private static ArrayList<String> lines = new ArrayList<String>(); static { lines.add("Among the rain"); lines.add("and ligths"); lines.add("I saw the figure 5"); lines.add("in gold"); lines.add("on a red"); lines.add("fire truck"); lines.add("moving"); lines.add("tense"); lines.add("unheeded"); lines.add("to gong clangs"); lines.add("siren howls"); lines.add("and wheels rumbling"); lines.add("through the dark city"); } public static String getTitle() { return title; } public static String getAuthor() { return author; } public static ArrayList<String> getLines() { return lines; } }
1、用DOM写XML文件
流程:
(1)创建一个空的Document对象(最顶层的DOM对象,包括了创建XML所须要的其它一切)。
(2)创建元素和属性,把元素和属性加到Document对象中。
(3)把Document对象的内容转换成String对象。
(4)把String对象写到目标文件中去。
import java.util.ArrayList; import java.io.*; import javax.xml.parsers.*; import javax.xml.transform.*; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import org.w3c.dom.*; public class XmlTest { public static void main(String[] args) { Document doc = createXMLContent1(); // 创建空文档 createElements(doc); // 创建XML String xmlContent = createXMLString(doc);// 创建字符串以表示XML writeXMLToFile1(xmlContent); } /*********** 用DOM写XML文件 ***********/ private static Document createXMLContent1() { Document doc = null; try { // 使应用程序可以从XML文档获取生成 DOM 对象树的解析器 DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance(); DocumentBuilder docBuilder = dbfac.newDocumentBuilder(); doc = docBuilder.newDocument(); // 作为 XML 声明 的一部分指定此文档是否是单独的的属性。未指定时,此属性为 false。 doc.setXmlStandalone(true); } catch (ParserConfigurationException pce) { System.out.println("Couldn't create a DocumentBuilder"); System.exit(1); } return doc; } private static void createElements(Document doc) { // 创建根元素 Element poem = doc.createElement("poem"); poem.setAttribute("title", Poem.getTitle()); poem.setAttribute("author", Poem.getAuthor()); // 把根元素加到文档里去 doc.appendChild(poem); // 创建子元素 for (String lineIn : Poem.getLines()) { Element line = doc.createElement("line"); Text lineText = doc.createTextNode(lineIn); line.appendChild(lineText); // 把每一个元素加到根元素里去 poem.appendChild(line); } } private static String createXMLString(Document doc) { // 将DOM转换成字符串 Transformer transformer = null; StringWriter stringWriter = new StringWriter(); try { TransformerFactory transformerFactory = TransformerFactory.newInstance(); transformer = transformerFactory.newTransformer(); // 是否应输出 XML 声明 transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); // 是否以XML格式自己主动换行 transformer.setOutputProperty(OutputKeys.INDENT, "yes"); // 创建字符串以包括XML stringWriter = new StringWriter(); StreamResult result = new StreamResult(stringWriter);// 充当转换结果的持有者 DOMSource source = new DOMSource(doc); transformer.transform(source, result); } catch (TransformerConfigurationException e) { System.out.println("Couldn't create a Transformer"); System.exit(1); } catch (TransformerException e) { System.out.println("Couldn't transforme DOM to a String"); System.exit(1); } return stringWriter.toString(); } private static void writeXMLToFile1(String xmlContent) { String fileName = "E:\\test\\domoutput.xml"; try { File domOutput = new File(fileName); FileOutputStream domOutputStream = new FileOutputStream(domOutput); domOutputStream.write(xmlContent.getBytes()); domOutputStream.close(); System.out.println(fileName + " was successfully written"); } catch (FileNotFoundException e) { System.out.println("Couldn't find a file called" + fileName); System.exit(1); } catch (IOException e) { System.out.println("Couldn't write a file called" + fileName); System.exit(1); } }
2、用String写XML文件
这样的方法就比較简单。就是直接用字符串把整个XML文件描写叙述出来,然后保存文件。
二、读取XML文件
两种方式:用DOM读取XML文件和用SAX方式。一般DOM处理内容比較小的XML文件。而SAX能够处理随意大小的XML文件。
1、用DOM读取XML文件
public class XmlTest { public static void main(String[] args) { String fileName = "E:\\test\\domoutput.xml"; writeFileContentsToConsole(fileName); } /*********** 用DOM读取XML文件 ***********/ private static void writeFileContentsToConsole(String fileName) { Document doc = createDocument(fileName); Element root = doc.getDocumentElement();// 获取根元素 StringBuilder sb = new StringBuilder(); sb.append("The root element is named:\"" + root.getNodeName() + "\""); sb.append("and has the following attributes: "); NamedNodeMap attributes = root.getAttributes(); for (int i = 0; i < attributes.getLength(); i++) { Node thisAttribute = attributes.item(i); sb.append(thisAttribute.getNodeName()); sb.append("(\"" + thisAttribute.getNodeValue() + "\")"); if (i < attributes.getLength() - 1) { sb.append(","); } } System.out.println(sb);// 根元素的描写叙述信息 NodeList nodes = doc.getElementsByTagName("line"); for (int i = 0; i < nodes.getLength(); i++) { Element element = (Element) nodes.item(i); System.out.println("Found an element named \"" + element.getTagName() + "\"" + "With the following content: \"" + element.getTextContent() + "\""); } } private static Document createDocument(String fileName) {// 从文件创建DOM的Document对象 Document doc = null; try { File xmlFile = new File(fileName); DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance(); DocumentBuilder docBuilder = dbfac.newDocumentBuilder(); doc = docBuilder.parse(xmlFile);// 解析xml文件载入为dom文档 doc.setXmlStandalone(true); } catch (IOException e) { e.printStackTrace(); } catch (SAXException e) { e.printStackTrace(); } catch (ParserConfigurationException e) { e.printStackTrace(); } return doc; } }/* * Output: * The root element is named:"poem"and has the following attributes: author("William Carlos Williams"),title("The Great Figure") * Found an element named "line"With the following content: "Among the rain" * Found an element named "line"With the following content: "and ligths" * ... ... */// :~
2、用SAX读取XML文件
SAX是使用ContentHandler接口来公开解析事件,并且SAX包提供了一个默认实现类DefaultHandler,它的默认行为就是什么都不做。以下就通过XMLToConsoleHandler类来覆盖当中的一些方法,来捕获XML文件的内容。
import org.w3c.dom.CharacterData; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; public class XmlTest { public static void main(String[] args) { String fileName = "E:\\test\\domoutput.xml"; getFileContents(fileName); } private static void getFileContents(String fileName) { try { XMLToConsoleHandler handler = new XMLToConsoleHandler(); SAXParserFactory factory = SAXParserFactory.newInstance(); SAXParser saxParser = factory.newSAXParser(); saxParser.parse(fileName, handler); } catch (IOException e) { e.printStackTrace(); } catch (ParserConfigurationException e) { e.printStackTrace(); } catch (SAXException e) { e.printStackTrace(); } } } /*********** 用SAX读取XML文件 ***********/ class XMLToConsoleHandler extends DefaultHandler { public void characters(char[] content, int start, int length) throws SAXException { // 处理元素的真正内容 System.out.println("Found content: " + new String(content, start, length)); } public void endElement(String arg0, String localName, String qName)throws SAXException { System.out.println("Found the end of an element named \"" + qName + "\""); } public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { StringBuilder sb = new StringBuilder(); sb.append("Found the start of an element named \"" + qName + "\""); if (attributes != null && attributes.getLength() > 0) { sb.append(" with attributes named "); for (int i = 0; i < attributes.getLength(); i++) { String attributeName = attributes.getLocalName(i); String attributeValue = attributes.getValue(i); sb.append("\"" + attributeName + "\""); sb.append(" (value = "); sb.append("\"" + attributeValue + "\""); sb.append(")"); if (i < attributes.getLength() - 1) { sb.append(","); } } } System.out.println(sb.toString()); } }