XML 的解析方法

时间:2023-03-10 02:33:39
XML 的解析方法

四种XML解析方法:

(1)Dom生成和解析XML文档

*解析器读入整个文档,然后构建一个驻留内存的树结构,然后代码就可以使用 DOM 接口来操作这个树结构。
     * 优点:整个文档树在内存中,便于操作;支持删除、修改、重新排列等多种功能;
     * 缺点:将整个文档调入内存(包括无用的节点),浪费时间和空间;
     * 使用场合:一旦解析了文档还需多次访问这些数据;硬件资源充足(内存、CPU)。

(2)SAX生成和解析XML文档

* SAX ,事件驱动。
     * 当解析器发现元素开始、元素结束、文本、文档的开始或结束等时,发送事件,程序员编写响应这些事件的代码,保存数据。
     * 优点:不用事先调入整个文档,占用资源少;SAX解析器代码比DOM解析器代码小,适于Applet,下载。
     * 缺点:不是持久的;事件过后,若没保存数据,那么数据就丢了;
     * 无状态性;从事件中只能得到文本,但不知该文本属于哪个元素;
     * 使用场合:Applet;只需XML文档的少量内容,很少回头访问;机器内存少;

(3)DOM4J生成和解析XML文档

* DOM4J 是一个非常非常优秀的Java XML API,
     * 具有性能优异、功能强大和极端易用使用的特点,同时它也是一个开放源代码的软件。
     * 如今你可以看到越来越多的 Java 软件都在使用 DOM4J 来读写 XML,特别值得一提的是连 Sun 的 JAXM 也在用 DOM4J。

(4)JDOM生成和解析XML

*为减少DOM、SAX的编码量,出现了JDOM;
     *优点:20-80原则,极大减少了代码量。
     *使用场合:要实现的功能简单,如解析、创建等,
     *但在底层,JDOM还是使用SAX(最常用)、DOM、Xanan文档。

首先编写一个要解析的test.xml文件

  1. <?xml version="1.0" encoding="UTF-8" standalone="no"?>
  2. <employees>
  3. <employee>
  4. <name>wxyfree</name>
  5. <age>30</age>
  6. </employee>
  7. <employee>
  8. <name>freewxy</name>
  9. <age>22</age>
  10. </employee>
  11. </employees>

然后,编写一个XMLDocument接口

  1. /**
  2. * 定义XML文档建立与解析的接口
  3. * @author wxy
  4. *
  5. */
  6. public interface XMLDocument {
  7. /**
  8. *建立XML文档
  9. * @param fileName 文件全路径名
  10. */
  11. public void createXML(String fileName);
  12. /**
  13. * 解析XML文档
  14. * @param fileName 文件全路径名
  15. */
  16. public void parseXML(String fileName);
  17. }

一、

  1. package review.testXML;
  2. import java.io.FileNotFoundException;
  3. import java.io.FileOutputStream;
  4. import java.io.IOException;
  5. import java.io.PrintWriter;
  6. import javax.xml.parsers.DocumentBuilder;
  7. import javax.xml.parsers.DocumentBuilderFactory;
  8. import javax.xml.parsers.ParserConfigurationException;
  9. import javax.xml.transform.OutputKeys;
  10. import javax.xml.transform.Transformer;
  11. import javax.xml.transform.TransformerConfigurationException;
  12. import javax.xml.transform.TransformerException;
  13. import javax.xml.transform.TransformerFactory;
  14. import javax.xml.transform.dom.DOMSource;
  15. import javax.xml.transform.stream.StreamResult;
  16. import org.w3c.dom.Document;
  17. import org.w3c.dom.Element;
  18. import org.w3c.dom.Node;
  19. import org.w3c.dom.NodeList;
  20. import org.xml.sax.SAXException;
  21. /**
  22. * Dom生成和解析XML文档
  23. * 为 XML 文档的已解析版本定义了一组接口。
  24. * 解析器读入整个文档,然后构建一个驻留内存的树结构,然后代码就可以使用 DOM 接口来操作这个树结构。
  25. * 优点:整个文档树在内存中,便于操作;支持删除、修改、重新排列等多种功能;
  26. * 缺点:将整个文档调入内存(包括无用的节点),浪费时间和空间;
  27. * 使用场合:一旦解析了文档还需多次访问这些数据;硬件资源充足(内存、CPU)。
  28. * @param args
  29. */
  30. public class DomDemo implements XMLDocument  {
  31. private Document document;
  32. private String fileName;
  33. public void init(){
  34. try{
  35. DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
  36. DocumentBuilder builder=factory.newDocumentBuilder();
  37. this.document=builder.newDocument();
  38. }catch(ParserConfigurationException e){
  39. System.out.println(e.getMessage());
  40. }
  41. }
  42. @Override
  43. public void createXML(String fileName) {
  44. Element root=this.document.createElement("employees");//创建根元素
  45. this.document.appendChild(root);
  46. Element employee=this.document.createElement("employee");//创建子元素
  47. Element name=this.document.createElement("name");//添加元素的属性
  48. name.appendChild(this.document.createTextNode("wxyfree"));
  49. employee.appendChild(name);//将元素添加到子元素中
  50. Element sex=this.document.createElement("sex");
  51. sex.appendChild(this.document.createTextNode("m"));
  52. Element age=this.document.createElement("age");
  53. age.appendChild(this.document.createTextNode("30"));
  54. employee.appendChild(age);
  55. root.appendChild(employee);//将子元素添加到根元素中
  56. TransformerFactory tf=TransformerFactory.newInstance();//此抽象类的实例能够将源树转为结果树
  57. try{
  58. Transformer transformer=tf.newTransformer();
  59. DOMSource source=new DOMSource(document);//创建带有DOM节点的新输入源
  60. transformer.setOutputProperty(OutputKeys.ENCODING,"UTF-8");//设置转换中世纪的输出属性
  61. transformer.setOutputProperty(OutputKeys.INDENT, "yes");//
  62. PrintWriter pw=new PrintWriter(new FileOutputStream(fileName));
  63. StreamResult result=new StreamResult(pw);//充当转换结果的持有者,可以为xml、纯文本、HTML或某些其他格式的标记
  64. transformer.transform(source, result);//将XML Source转换为Result
  65. System.out.println("生成XML文件成功");
  66. }catch(TransformerConfigurationException e){
  67. System.out.println(e.getMessage());
  68. } catch (TransformerException e) {
  69. System.out.println(e.getMessage());
  70. } catch (FileNotFoundException e) {
  71. System.out.println(e.getMessage());
  72. }
  73. }
  74. @Override
  75. public void parseXML(String fileName) {
  76. DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();
  77. DocumentBuilder db;
  78. try {
  79. db = dbf.newDocumentBuilder();
  80. Document document = db.parse(fileName);
  81. NodeList employees=document.getChildNodes();
  82. for(int i=0;i<employees.getLength();i++){
  83. Node employee=employees.item(i);
  84. NodeList employeeInfo=employee.getChildNodes();
  85. for(int j=0;j<employeeInfo.getLength();j++){
  86. Node node=employeeInfo.item(j);
  87. NodeList employeeMeta=node.getChildNodes();
  88. for(int k=0;k<employeeMeta.getLength();k++){
  89. System.out.println(employeeMeta.item(k).getNodeName()+":"+employeeMeta.item(k).getTextContent());
  90. }
  91. }
  92. }
  93. } catch (ParserConfigurationException e) {
  94. // TODO Auto-generated catch block
  95. e.printStackTrace();
  96. } catch (SAXException e) {
  97. // TODO Auto-generated catch block
  98. e.printStackTrace();
  99. } catch (IOException e) {
  100. // TODO Auto-generated catch block
  101. e.printStackTrace();
  102. }
  103. System.out.println("解析完毕");
  104. }
  105. public static void main(String[] args){
  106. DomDemo d=new DomDemo();
  107. d.init();
  108. d.createXML("conf/test2.xml");
  109. d.parseXML("conf/test.xml");
  110. }
  111. }

二、

  1. package review.testXML;
  2. import java.io.FileInputStream;
  3. import java.io.FileNotFoundException;
  4. import java.io.IOException;
  5. import java.io.InputStream;
  6. import javax.xml.parsers.ParserConfigurationException;
  7. import javax.xml.parsers.SAXParser;
  8. import javax.xml.parsers.SAXParserFactory;
  9. import org.xml.sax.Attributes;
  10. import org.xml.sax.HandlerBase;
  11. import org.xml.sax.SAXException;
  12. import org.xml.sax.helpers.DefaultHandler;
  13. /**
  14. * SAX ,事件驱动。
  15. * 当解析器发现元素开始、元素结束、文本、文档的开始或结束等时,发送事件,程序员编写响应这些事件的代码,保存数据。
  16. * 优点:不用事先调入整个文档,占用资源少;SAX解析器代码比DOM解析器代码小,适于Applet,下载。
  17. * 缺点:不是持久的;事件过后,若没保存数据,那么数据就丢了;
  18. *      无状态性;从事件中只能得到文本,但不知该文本属于哪个元素;
  19. * 使用场合:Applet;只需XML文档的少量内容,很少回头访问;机器内存少;
  20. * @author wxy
  21. *
  22. */
  23. public class SaxDemo implements XMLDocument{
  24. @Override
  25. public void createXML(String fileName) {
  26. System.out.println("<<"+fileName+">>");
  27. }
  28. @Override
  29. public void parseXML(String fileName) {
  30. SAXParserFactory saxfac=SAXParserFactory.newInstance();
  31. try {
  32. SAXParser saxParser=saxfac.newSAXParser();
  33. InputStream ins=new FileInputStream(fileName);
  34. saxParser.parse(ins,new MySAXHandler());
  35. } catch (ParserConfigurationException e) {
  36. System.out.println(e.getMessage());
  37. } catch (SAXException e) {
  38. System.out.println(e.getMessage());
  39. } catch (FileNotFoundException e) {
  40. System.out.println(e.getMessage());
  41. } catch (IOException e) {
  42. System.out.println(e.getMessage());
  43. }
  44. }
  45. /**
  46. * @param args
  47. */
  48. public static void main(String[] args) {
  49. SaxDemo s=new SaxDemo();
  50. s.parseXML("conf/test.xml");
  51. }
  52. }
  53. class MySAXHandler extends DefaultHandler{
  54. boolean hasAttribute=false;
  55. Attributes attributes=null;
  56. /**
  57. *  Receive notification of the beginning of the document.
  58. */
  59. public void startDocument()throws SAXException{
  60. System.out.print("文档开始打印了");
  61. }
  62. /**
  63. * Receive notification of the end of the document.
  64. */
  65. public void endDocument()throws SAXException{
  66. System.out.print("文档开始结束了");
  67. }
  68. /**
  69. * Receive notification of the start of an element.
  70. * @param uri The Namespace URI, or the empty string if the
  71. *        element has no Namespace URI or if Namespace
  72. *        processing is not being performed.
  73. * @param localName The local name (without prefix), or the
  74. *        empty string if Namespace processing is not being
  75. *        performed.
  76. * @param qName The qualified name (with prefix), or the
  77. *        empty string if qualified names are not available.
  78. * @param attributes The attributes attached to the element.  If
  79. *        there are no attributes, it shall be an empty
  80. *        Attributes object.
  81. * @exception org.xml.sax.SAXException Any SAX exception, possibly
  82. *            wrapping another exception.
  83. */
  84. public void startElement(String uri,String localName,String qName,Attributes attributes)throws SAXException{
  85. if(qName.equals("employees")){return;}
  86. if(qName.equals("employee")){
  87. System.out.print(qName);
  88. }
  89. if(attributes.getLength()>0){
  90. this.attributes=attributes;
  91. this.hasAttribute=true;
  92. }
  93. }
  94. /**
  95. * Receive notification of the end of an element.
  96. * @param uri The Namespace URI, or the empty string if the
  97. *        element has no Namespace URI or if Namespace
  98. *        processing is not being performed.
  99. * @param localName The local name (without prefix), or the
  100. *        empty string if Namespace processing is not being
  101. *        performed.
  102. * @param qName The qualified name (with prefix), or the
  103. *        empty string if qualified names are not available.
  104. * @exception org.xml.sax.SAXException Any SAX exception, possibly
  105. *            wrapping another exception.
  106. */
  107. public void endElement(String uri,String localName,String qNaqme)throws SAXException{
  108. if(hasAttribute&&(attributes!=null)){
  109. for(int i=0;i<attributes.getLength();i++){
  110. System.out.print(attributes.getQName(0)+attributes.getValue(0));
  111. }
  112. }
  113. }
  114. /**
  115. * Receive notification of character data inside an element.
  116. * @param ch The characters.
  117. * @param start The start position in the character array.
  118. * @param length The number of characters to use from the
  119. *               character array.
  120. */
  121. public void characters(char[] ch,int start,int length)throws SAXException{
  122. System.out.print(new String(ch,start,length));
  123. }
  124. }

三、

  1. package review.testXML;
  2. import java.io.File;
  3. import java.io.FileWriter;
  4. import java.io.IOException;
  5. import java.io.Writer;
  6. import java.util.Iterator;
  7. import org.dom4j.Document;
  8. import org.dom4j.DocumentException;
  9. import org.dom4j.DocumentHelper;
  10. import org.dom4j.Element;
  11. import org.dom4j.io.SAXReader;
  12. import org.dom4j.io.XMLWriter;
  13. /**
  14. *  Dom4j 生成XML文档与解析XML文档
  15. * DOM4J 是一个非常非常优秀的Java XML API,
  16. * 具有性能优异、功能强大和极端易用使用的特点,同时它也是一个开放源代码的软件。
  17. * 如今你可以看到越来越多的 Java 软件都在使用 DOM4J 来读写 XML,特别值得一提的是连 Sun 的 JAXM 也在用 DOM4J。
  18. * @author wxy
  19. *
  20. */
  21. public class Dom4jDemo implements XMLDocument{
  22. @Override
  23. public void createXML(String fileName) {
  24. Document document = DocumentHelper.createDocument();
  25. Element employees=document.addElement("employees");
  26. Element employee=document.addElement("employee");
  27. Element name=employee.addElement("name");
  28. name.setText("wxy");
  29. Element sex=employee.addElement("sex");
  30. name.setText("f");
  31. Element age=employee.addElement("age");
  32. name.setText("29");
  33. try {
  34. Writer fileWriter=new FileWriter(fileName);
  35. XMLWriter xmlWriter=new XMLWriter(fileWriter);
  36. xmlWriter.write(document);
  37. xmlWriter.close();
  38. } catch (IOException e) {
  39. System.out.println(e.getMessage());
  40. }
  41. }
  42. @Override
  43. public void parseXML(String fileName) {
  44. File inputXML=new File(fileName);
  45. SAXReader saxReader=new SAXReader();
  46. try {
  47. Document document=saxReader.read(inputXML);
  48. Element employees=document.getRootElement();
  49. for(Iterator i=employees.elementIterator();i.hasNext();){
  50. Element employee=(Element)i.next();
  51. for(Iterator j=employee.elementIterator();j.hasNext();){
  52. Element node=(Element)j.next();
  53. System.out.println(node.getName()+":"+node.getText());
  54. }
  55. }
  56. } catch (DocumentException e) {
  57. System.out.println(e.getMessage());
  58. }
  59. System.out.println("dom4j parserXML");
  60. }
  61. public static void main(String[] args) {
  62. Dom4jDemo d=new Dom4jDemo();
  63. d.parseXML("conf/test.xml");
  64. }
  65. }

四、

  1. package review.testXML;
  2. import java.io.FileNotFoundException;
  3. import java.io.FileOutputStream;
  4. import java.io.IOException;
  5. import java.util.List;
  6. import org.jdom.Document;
  7. import org.jdom.Element;
  8. import org.jdom.JDOMException;
  9. import org.jdom.input.SAXBuilder;
  10. import org.jdom.output.XMLOutputter;
  11. /**
  12. * JDOM生成和解析XML
  13. *为减少DOM、SAX的编码量,出现了JDOM;
  14. *优点:20-80原则,极大减少了代码量。
  15. *使用场合:要实现的功能简单,如解析、创建等,
  16. *但在底层,JDOM还是使用SAX(最常用)、DOM、Xanan文档。
  17. * @author wxy
  18. *
  19. */
  20. public class JDomDemo implements XMLDocument{
  21. @Override
  22. public void createXML(String fileName) {
  23. Document document;
  24. Element root;
  25. root=new Element("employees");
  26. document=new Document(root);
  27. Element employee=new Element("employee");
  28. root.addContent(employee);
  29. Element name=new Element("name");
  30. name.setText("wxywxy");
  31. employee.addContent(name);
  32. Element sex=new Element("sex");
  33. sex.setText("m");
  34. employee.addContent(sex);
  35. Element age=new Element("age");
  36. age.setText("25");
  37. employee.addContent(age);
  38. XMLOutputter XMLOut=new XMLOutputter();
  39. try {
  40. XMLOut.output(document, new FileOutputStream(fileName));
  41. } catch (FileNotFoundException e) {
  42. System.out.println(e.getMessage());
  43. } catch (IOException e) {
  44. System.out.println(e.getMessage());
  45. }
  46. }
  47. @Override
  48. public void parseXML(String fileName) {
  49. SAXBuilder builder=new SAXBuilder(false);
  50. try {
  51. Document document=builder.build(fileName);
  52. Element employees=document.getRootElement();
  53. List employeeList=employees.getChildren("employee");
  54. for(int i=0;i<employeeList.size();i++){
  55. Element employee=(Element)employeeList.get(i);
  56. List employeeInfo=employee.getChildren();
  57. for(int j=0;j<employeeInfo.size();j++){
  58. System.out.println(((Element)employeeInfo.get(j)).getName()+":"+((Element)employeeInfo.get(j)).getText());
  59. }
  60. }
  61. } catch (JDOMException e) {
  62. System.out.println(e.getMessage());
  63. } catch (IOException e) {
  64. System.out.println(e.getMessage());
  65. }
  66. }
  67. public static void main(String[] args){
  68. JDomDemo jd=new JDomDemo();
  69. jd.parseXML("conf/test.xml");
  70. }
  71. }