XML解析
DOM(Document Object Model)解析
优点:增删改查方便
缺点:需要读取整个xml才能构建DOM树。对于较大的xml,容易内存溢出
SAX(Simple API for XML)解析
优点:在读取文档的时候,即对文档进行处理,而不必等到整个文档装载完才会文档进行操作
缺点:不是持久的;事件过后,若没保存数据,那么数据就丢了;无状态性;从事件中只能得到文本,但不知该文本属于哪个元素
适用于只查询
JAXP(Java API for XML Processing)
可以进行DOM解析和SAX解析,由SUN公司提供,存在于JDK中
所在包:
org.w3c.dom:提供DOM方式解析XML的标准接口
org.xml.sax:提供SAX方式解析XML的标准接口
javax.xml:提供了解析XML文档的类
JAXP调用dom方式创建xml
创建一个如下所示的xml文件
<?xml version="1.0" encoding="UTF-8"?> <recipe type="dessert"> <recipename cuisine="american" servings="1">Ice Cream Sundae</recipename> </recipe>
java代码如下:
public static void createXML(String fileName) throws Exception{ //获取DocumentBuilderFactory DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); //获取DocumentBuilder DocumentBuilder builder = factory.newDocumentBuilder(); //获取Document对象 Document document = builder.newDocument(); //设置xml声明 document.setXmlStandalone(false);//指定此文档是否是单独的的属性 //创建跟元素 <recipe type="dessert"> Element rootElement = document.createElement("recipe"); //设置元素属性 rootElement.setAttribute("type", "dessert"); //创建元素<recipename> Element recipename = document.createElement("recipename"); //为recipename元素添加属性 recipename.setAttribute("cuisine", "american"); recipename.setAttribute("servings", "1"); //设置recipename元素中的值 recipename.setTextContent("Ice Cream Sundae"); rootElement.appendChild(recipename); //将根元素添加到document中 document.appendChild(rootElement); //将xml映射到文件 boolean flag = true; try{ //获取TransformerFactorty 用于创建 Transformer 和 Templates 对象。 TransformerFactory tf = TransformerFactory.newInstance(); //获取Transformer对象 处理来自不同源的 XML,并将转换输出写入各种接收器 //注意:在多线程同时运行时不能使用此类的对象 Transformer transformer = tf.newTransformer(); DOMSource source = new DOMSource(document); //设置编码格式 transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); //设置indent = "yes" | "no". indent 指定了当输出结果树时,Transformer 是否可以添加额外的空白;其值必须为 yes 或 no。就是幽默诶有进行格式化 transformer.setOutputProperty(OutputKeys.INDENT, "yes"); PrintWriter pw = new PrintWriter(new FileOutputStream(fileName)); StreamResult result = new StreamResult(pw); transformer.transform(source, result); }catch(Exception e){ flag = false; e.printStackTrace(); } if(flag){ System.out.println("生成XML文件成功!"); }else{ System.out.println("生成XML文件失败!"); } }
JAXP调用SAX解析XML
public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException { //创建解析器工厂, SAXParserFactory spf = SAXParserFactory.newInstance(); //得到解析器, SAXParser parser = spf.newSAXParser(); //得到读取器 XMLReader reader = parser.getXMLReader(); //给内容注册内容处理器 // reader.setContentHandler(new MyContentHandler()); reader.setContentHandler(new DefaultHandler(){ public void startDocument() throws SAXException { // TODO Auto-generated method stub super.startDocument(); System.out.println("读取文档开始"); } public void endDocument() throws SAXException { // TODO Auto-generated method stub super.endDocument(); System.out.println("读取文档结束"); } }); //解析文档 reader.parse("book.xml"); }
由于dom用来增删改比较方便,所以选择了用期进行创建修改操作,而SAX方式可以快速的进行查找便利,所以选择用来做解析遍历,此处就不在编写dom解析xml的方式了。
第三方解析XML--DOM4J
解析XML,对XML进行遍历
首先要获取到一个Document对象
public Document parse(URL url) throws DocumentException { SAXReader reader = new SAXReader(); Document document = reader.read(url); return document; }
然后开始进行遍历,在文档中找到两种方法见代码:
//方法1 public void bar(Document document) throws DocumentException { Element root = document.getRootElement(); // iterate through child elements of root for ( Iterator i = root.elementIterator(); i.hasNext(); ) { Element element = (Element) i.next(); // do something } // iterate through child elements of root with element name "foo" for ( Iterator i = root.elementIterator( "foo" ); i.hasNext(); ) { Element foo = (Element) i.next(); // do something } // iterate through attributes of root for ( Iterator i = root.attributeIterator(); i.hasNext(); ) { Attribute attribute = (Attribute) i.next(); // do something } } //方法2 public void treeWalk(Document document) { treeWalk( document.getRootElement() ); } public void treeWalk(Element element) { for ( int i = 0, size = element.nodeCount(); i < size; i++ ) { Node node = element.node(i); if ( node instanceof Element ) { treeWalk( (Element) node ); } else { // do something.... } } }
在文档中表明:如果说xml文件比较大的话,建议用第二种方法,可以避免了创建每个循环迭代器对象的成本。
Dom4j创建xml
/** *创建XML */ public Document createDocument() { Document document = DocumentHelper.createDocument(); Element root = document.addElement( "root" ); Element author1 = root.addElement( "author" ) .addAttribute( "name", "James" ) .addAttribute( "location", "UK" ) .addText( "James Strachan" ); Element author2 = root.addElement( "author" ) .addAttribute( "name", "Bob" ) .addAttribute( "location", "US" ) .addText( "Bob McWhirter" ); return document; } /** *将XML进行持久化(保存到文件) */ public void write(Document document) throws IOException { XMLWriter writer = new XMLWriter( new FileWriter( "output.xml" ) ); writer.write( document ); writer.close(); /*这个地方是定义输出格式 *OutputFormat.createPrettyPrint() 方便阅读的格式(带空格,带换行) *OutputFormat.createCompactFormat();没有空格换行 *format.setEncoding(String encoding) 可以设置编码格式,默认utf-8 */ OutputFormat format = OutputFormat.createPrettyPrint(); writer = new XMLWriter( System.out, format ); writer.write( document ); }
以上dom4j代码摘自文档中
原文地址:http://stramkismet.blog.51cto.com/10090092/1657303