解析xml的几种方法,他们的原理,比较 以及JAVA源码
第一种方法 ---------------------------------------------------------------------------------------------------- 目前常用的XML的解析器主要有:SAX,DOM,Xerces 1、SAX处理的优点非常类似于流媒体的优点。分析能够立即开始,而不是等待所有的数据被处理。而且,由于应用程序只是在读取数据时检查数据,因此不需要将数据存储在内存中。这对于大型文档来说是个巨大的优点。事实上,应用程序甚至不必解析整个文档;它可以在某个条件得到满足时停止解析。一般来说,SAX 还比它的替代者 DOM 快许多。另一方面,由于应用程序没有以任何方式存储数据,使用 SAX 来更改数据或在数据流中往后移是不可能的。 2、DOM 以及广义的基于树的处理具有几个优点。首先,由于树在内存中是持久的,因此可以修改它以便应用程序能对数据和结构作出更改。它还可以在任何时候在树中上下导航,而不是像 SAX 那样是一次性的处理。DOM 使用起来也要简单得多。另一方面,在内存中构造这样的树涉及大量的开销。大型文件完全占用系统内存容量的情况并不鲜见。此外,创建一棵 DOM 树可能是一个缓慢的过程。 3、选择 DOM 还是选择 SAX,这取决于下面几个因素: 4、SAX,DOM是两种对XML文档进行分析的方法(没有具体的实现,只有接口),所以不是解释器,如果光有他们,你是完成不了对xml文档的处理的。SAX的包是org.xml.sax,DOM的包是org.w3c.dom,包的名称很重要,它有助于你理解他们之间的关系。 5、jaxp是api,他封装了sax/dom两种接口。并在sax/dom的基础之上,作了一套比较简单的api以供开发人员使用。jaxp的包是javax.xml.parsers,可以看看jaxp的源文件,它的文件中包含了对sax或者dom的引用(import)jaxp也不是具体的实现,他只是一套api。如果你仅仅有jaxp那是无法工作的,(其实jaxp只是完成对sax、dom的包装,生成了DocumentBuilderFactory/DocumentBuilder和SAXParserFactory SAXParser。也就是设计模式中的工厂模式,他的好处就是具体的对象( 解释器)建立由子类完成) 6、xerces解释器(号称地球上最快的xml解释器)在xerces中对jaxp中定义的SAXParser SAXParserFactory DocumentBuilder DocumentBuilderFactory进行了继承(extends)对应SAXParserImpl XParserFactoryImpl DocumentBuilderImpl DocumentBuilderFactoryImpl这就是为什么你的classpath中只要有xerces.jar(其中包含了sax dom jaxp )和 xercesImpl.jar就可以的原因了. ---------------------------------------------------------------------------------------------------- //xml解析的几种方式 //相关搜索: xml,解析 //1.dom解析: package com.yzt.xml.lixin; import javax.xml.parsers.*; //import org.xml.sax.*; import java.io.*; import org.w3c.dom.*; public class DomParserDemo { static Document document; public static void main(String[] args) { //DOM解释器总类,用他创建DOM解释器 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); try { //创建DOM解释器 DocumentBuilder builder = factory.newDocumentBuilder(); //取得xml文件 document = builder.parse(new File("F:/XmlProject/src/com/lixin/Test.xml")); //取得结构树的根节点、 Element persons = document.getDocumentElement(); //取得标识为Persons的集合 NodeList personList = persons.getElementsByTagName("Person"); //声明属性数组 String [] personAttributes = {"id","name","genda","birthday","occupation","email"}; //循环访问没个person for(int i=0;i<personList.getLength();++i){ //取得数据 //把里面的方法写上注释;用自己的理解写********* Element onePerson = (Element) personList.item(i); for(int j=0;j<personAttributes.length;j++){ NodeList data = onePerson.getElementsByTagName(personAttributes[j]); Node oneData = data.item(0).getFirstChild(); String nodeValue = oneData.getNodeValue(); //显示person数据 // System.out.println(nodeValue); System.out.println(" "+personAttributes[j]+ "=" +nodeValue); } //在新的一行显示下一个数据 System.out.println(""); } } catch (Exception ex) { ex.printStackTrace(); } } } //2.sax解析: package com.yzt.xml.lixin; import java.io.*; import org.xml.sax.*; import org.xml.sax.helpers.DefaultHandler; import javax.xml.parsers.*; class SaxContentHandler extends DefaultHandler{ static private Writer out; //声明文件写出器 private String indentString = " ";//显示不同层次的元素空格 private int indentLevel = 0; //标识元素的层次 //创建SAX解释器,并激活ContentHanddler事件的处理机制 public static void main(String[] args) { //创建ContentHandler事件接口 DefaultHandler handler = new SaxContentHandler(); //SAX解释器总类,用来创建SAX解释器 SAXParserFactory factory = SAXParserFactory.newInstance(); try { //将System.out写出器,使用GBK的编码方式,赋给变量out out = new OutputStreamWriter(System.out,"GB2312"); //创建SAX解释器 SAXParser saxParser = factory.newSAXParser(); //取得xml文件,将激活ContentHandler事件 //saxParser.parse(new File("Test.xml"),handler); F:/XmlProject/src/com/lixin saxParser.parse(new File("D:/workspace/review/WebRoot/Test.xml"),handler); } catch (Exception ex) { ex.printStackTrace(); } System.exit(0);//清空程序占用的内存,推出程序 ; 终止当前正在运行的 Java 虚拟机。 } //XML文档节点开始事件 /**startElement(String namepaceURI,String IName,String qName,Attributes attrs)接收元素开始的通知。 * * IName 包含前缀名的元素名字 * qName 不包含前缀名的元素名字 * attrs 元素的属性名字 * */ public void startElement(String namepaceURI,Attributes attrs){ try { indentLevel++; newLine(); String eName = IName; //取得元素的名称 if("".equals(eName)){ eName = qName; printOut("<"+eName+">"); } } catch (Exception ex) { ex.printStackTrace(); } } //读入元素之间数据的方法 ;;;接收元素中字符数据的通知。 public void characters(char buf[],int offset,int len){ try { /** * String(char[] value,int count) * 分配一个新的 String,它包含来自该字符数组参数的一个子数组的字符。 * */ String s = new String(buf,offset,len); if(!s.trim().equals("")){ printOut(" "+s+" "); } } catch (Exception ex) { ex.printStackTrace(); } } //xml文档节点的结束事件 public void endElement(String namespaceURI,String sName,String qName){ try { if(qName.equals("")|qName.equals("")){ newLine(); } printOut("</"+qName+">"); indentLevel--; } catch (Exception ex) { ex.printStackTrace(); } } //显示xml文档内容的方法 private void printOut(String s){ try { out.write(s); out.flush(); } catch (Exception ex) { ex.printStackTrace(); } } //显示新的一行的方法 public void newLine(){ //System.getProperty("line.separator");获得指定键指示的系统属性。 line 有各种控件 String lineEnd = System.getProperty("line.separator"); try { out.write(lineEnd); for(int i=0;i<indentLevel;i++){ out.write(indentString); } } catch (Exception ex) { ex.printStackTrace(); } } } ============================================ package com.yzt.xml.lixin; import java.io.IOException; import javax.xml.parsers.*; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; public class SaxParser1 extends DefaultHandler { public static void main(String[] args) { String uri ="D:/workspace/review/WebRoot/Test.xml"; try { SAXParserFactory parserFactory = SAXParserFactory.newInstance(); parserFactory.setValidating(false); parserFactory.setNamespaceAware(false); SaxParser1 SaxParser1Instance = new SaxParser1(); SAXParser parser = parserFactory.newSAXParser(); parser.parse(uri,SaxParser1Instance); } catch (IOException exception) { exception.printStackTrace(); } catch (SAXException exception) { exception.printStackTrace(); } catch (ParserConfigurationException exception) { exception.printStackTrace(); } catch (FactoryConfigurationError exception) { exception.printStackTrace(); } } /** * @接收元素中字符数据的通知。 */ public void characters(char[] ch,int start,int length) throws SAXException { String s = new String(ch,start,length); System.out.print(""+s+""); } } //3.dom4j生成xml和修改(修改还有点问题没能实现): package com.yzt.xml; import java.io.*; import java.util.List; import java.util.Iterator; import org.dom4j.*; import org.dom4j.io.OutputFormat; import org.dom4j.io.SAXReader; import org.dom4j.io.XMLWriter; public class dom4j { /*dom4j 是一种解析 XML 文档的开放源代码 XML 框架。 *与 W3C DOM API 相比,使用 dom4j 所包含的解析器的好处是 dom4j 拥有本地的 XPath 支持。 *DOM 解析器不支持使用 XPath 选择节点。 **/ public dom4j(){ } //创建自己的xml public int createXMLFile(String filename){ int returnValue=0; Document document=DocumentHelper.createDocument(); Element booksElement=document.addElement("books"); booksElement.addComment("作者:yzt2008812"); Element bookElement=booksElement.addElement("book"); bookElement.addAttribute("show","YES"); Element titleElement=bookElement.addElement("title"); titleElement.setText("Dom4j实例应用"); bookElement=booksElement.addElement("book"); bookElement.addAttribute("show","yes"); titleElement.setText("Lucene学习指南"); bookElement=booksElement.addElement("book"); bookElement.addAttribute("show","no"); titleElement=bookElement.addElement("title"); titleElement.setText("spring全攻略"); Element ownerElement=booksElement.addElement("owner"); ownerElement.setText("我的测试xml"); try{ XMLWriter writer=new XMLWriter(new FileWriter(new File(filename))); writer.write(document); writer.close(); returnValue=1; }catch(Exception ex){ ex.printStackTrace(); } return returnValue; } //格式化xml文档,并解决中文问题 public int formatXMLFile(String filename){ int returnValue=0; try{ SAXReader saxReader =new SAXReader(); Document document=saxReader.read(new File(filename)); XMLWriter output=null; OutputFormat format=OutputFormat.createPrettyPrint(); format.setEncoding("GBK"); output.write(document);; output.close(); returnValue=1; }catch(Exception ex){ ex.printStackTrace(); } return returnValue; } //修改并另存为xml public int change_XMLFile(String filename,String newfilename){ int returnValue=0; try{ SAXReader saxReader=new SAXReader(); Document document=saxReader.read(new File(filename)); /* 修改内容之一: 如果book节点中show参数的内容为yes,则修改成no * * 先用xpath查找对象 * * 注意:selectNodes()参数的格式: * 节点名[@属性名='属性值'],如:book[@url='dom4j.com'] * 如果有多个节点,用“/”分开,如:book[@url='dom4j.com']/title[@id='123'] **/ List list=document.selectNodes("books/book/@show"); Iterator iter=list.iterator(); while(iter.hasNext()){ Attribute attribute=(Attribute)iter.next(); if(attribute.getValue().equals("YES")){ attribute.setValue("Noooooo"); } } }catch(Exception ex){ ex.printStackTrace(); } return returnValue; } //main方法执行操作 public static void main(String []args){ dom4j temp=new dom4j(); System.out.println(temp.createXMLFile("c:/catalog/yzt.xml")); System.out.println(temp.change_XMLFile("c:/catalog/yzt.xml","c:/catalog/yzt22.xml")); } } /jdom解析修改xml(修改部分还是有点问题!): package com.yzt.xml; import java.io.IOException; import org.jdom.Document; import org.jdom.Element; import org.jdom.input.SAXBuilder; import org.jdom.output.Format; import org.jdom.output.XMLOutputter; import java.io.*; import java.io.FileWriter; import org.jdom.input.*; import org.jdom.output.*; import java.util.List; import org.jdom.*; public class jdom { private Element customer,name,age,sex,address,street,city,district; //构造方法生成xml public jdom(){ customer=new Element("customer"); Document document =new Document(customer); name=new Element("name"); age=new Element("age"); sex=new Element("sex"); address=new Element("address"); street=new Element("street"); city=new Element("city"); district=new Element("district"); name.addContent("张三"); age.addContent("25"); sex.addContent("湖北"); city.addContent("北京"); street.addContent("上地三街"); district.addContent("海淀区"); address.addContent(street); address.addContent(city); address.addContent(district); customer.addContent(name); customer.addContent(age); customer.addContent(sex); customer.addContent(address); XMLOutputter fmt=new XMLOutputter(); try{ FileWriter writer=new FileWriter("c:/catalog/customer.xml"); Format f=Format.getPrettyFormat(); f.setEncoding("GB2312"); fmt.output(document,writer); }catch(IOException e){ e.printStackTrace(); } jdom_change_xml(); } //修改xml public int jdom_change_xml(){ int returnValue=0; System.out.println(returnValue+"*********"); try{ SAXBuilder sab=new SAXBuilder(); Document doc=sab.build(new FileInputStream("c:/catalog/sampleA.xml")); Element root=doc.getRootElement(); List books=root.getChildren(); Element book=(Element)books.get(0); Attribute newattribute=new Attribute("QQQQ","WWWW"); book.setAttribute(newattribute); Element author=(Element)book.getChild("author"); author.setText("yztxlty"); System.out.println(author.getText().toString()+"7777"); Element price =book.getChild("price"); price.setText(Float.toString(1000000)); String indent =" "; boolean newLines=true; XMLOutputter outp=new XMLOutputter(); outp.output(doc,new FileOutputStream("c:/catalog/exampleB_yzt.xml")); System.out.print(returnValue+"+++++++++++"); return returnValue=1; }catch(Exception ex){ ex.printStackTrace(); //System.out.print(returnValue+"999999999"); } System.out.print(returnValue+"^^^^^^^^^^"); return returnValue; } public static void main(String []args){ new jdom(); //System.out.print(new jdom_change_xml()); } } //用到的xml文件 请参考 附件或者文档 //from: http://javalive.5d6d.com/frame.php?frameon=yes&referer=http://javalive.5d6d.com/thread-257-1-1.html (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |