xml文件的解析

你的名字 2021-04-06 14:40 682阅读 0赞

1. 解析方式

  1. 有两种解析方式,分别是:

    • DOM:即Document Object Model,文档对象模型,W3C推出的专门用于解析xml一种处理方式
    • SAX:Simple API for XML,一个开源社区推出的xml解析方式。

      区别是:

    • DOM方式会将整个xml文件解析成为一个树状结构,并加载到内存中,这种方式有一个缺点,如果xml文档过大,则解析会非常缓慢,甚至会产生内存溢出,优点就是因为在内存中生成了一个树状结构,所以可以对任意节点元素进行增删改操作。

    • SAX方式则是一边读一边解析,读到那个节点元素就解析那个,基于事件驱动,优点就是查询速度快而且不会发生内存溢出,缺点就是无法进行增删改操作。

      1. xml解析开发包:这三个解析包均支持DOM和SAX两种方式解析xml文件
    • JAXP:由sun公司推出的解析包,是JavaSE中的一部分,有以下几个包及其子包构成

      • org.w3c.dom:提供了以DOM方式解析xml文件的标准接口
      • org.xml.sax:提供了以SAX方式解析XML文件的标准接口
      • javax.xml:提供了解析XML文件的类,在javax.xml.parsers包中有几个工厂类,通过工厂类就可以获得以DOM方式或SAX方式解析XML文件解析器对象,分别是javax.xml.parsers.DocumentBuilderFactory 工厂类和 javax.xml.parsers.SAXParserFactory工厂类
    • Dom4J:由一个开源组织开发的解析实现包,常用这个包进行XML文件解析。
    • JDom:也是一个开源组织开发的解析包

2. 通过JDK中的解析器以DOM方式进行XML文件解析的实现代码

  1. 基础实现

    1. import java.io.IOException;
    2. import javax.xml.parsers.DocumentBuilder;
    3. import javax.xml.parsers.DocumentBuilderFactory;
    4. import javax.xml.parsers.ParserConfigurationException;
    5. import org.w3c.dom.Document;
    6. import org.w3c.dom.Node;
    7. import org.w3c.dom.NodeList;
    8. import org.xml.sax.SAXException;
    9. /**
    10. * @ClassName:Demo1
    11. * @Description:使用jdk中提供的包以DOM方式解析xml文件,代码步骤如下
    12. */
    13. public class Demo1 {
    14. public static void main(String[] args) {
    15. try {
    16. //1. 获取解析器的工程类对象DocumentBuilderFactory
    17. DocumentBuilderFactory domfac=DocumentBuilderFactory.newInstance();
    18. //2. 通过工厂类获取DOM解析器对象
    19. DocumentBuilder docb=domfac.newDocumentBuilder();
    20. //3. 解析指定路径的xml文件,并返回一个Document对象,Document对象中保存着整个xml文件中所有的元素节点
    21. Document doc=docb.parse("url");
    22. //4. 依据节点元素的名称来获取节点元素,返回的是一个NodeList对象
    23. NodeList list= doc.getElementsByTagName("name");
    24. //5. 从NodeList对象中遍历获取节点元素Node对象
    25. for(int i=0;i<list.getLength();i++){
    26. Node node= list.item(i);
    27. //6. 通过Node对象来获取节点内的具体信息,或者进行增删改当前节点及子节点操作
    28. System.out.println(node.getTextContent());;//获取当前节点中的文本数据
    29. }
    30. } catch (ParserConfigurationException e) {
    31. // TODO Auto-generated catch block
    32. e.printStackTrace();
    33. } catch (SAXException e) {
    34. // TODO Auto-generated catch block
    35. e.printStackTrace();
    36. } catch (IOException e) {
    37. // TODO Auto-generated catch block
    38. e.printStackTrace();
    39. }
    40. }
    41. }
  2. 添加子节点和删除子节点

    1. import java.io.IOException;
    2. import javax.xml.parsers.DocumentBuilder;
    3. import javax.xml.parsers.DocumentBuilderFactory;
    4. import javax.xml.parsers.ParserConfigurationException;
    5. import org.w3c.dom.Document;
    6. import org.w3c.dom.Element;
    7. import org.w3c.dom.Node;
    8. import org.w3c.dom.NodeList;
    9. import org.xml.sax.SAXException;
    10. public class Demo2 {
    11. public static void main(String[] args) {
    12. try {
    13. //1. 获取解析器的工程类对象DocumentBuilderFactory
    14. DocumentBuilderFactory domfac=DocumentBuilderFactory.newInstance();
    15. //2. 通过工厂类获取DOM解析器对象
    16. DocumentBuilder docb=domfac.newDocumentBuilder();
    17. //3. 解析指定路径的xml文件,并返回一个Document对象,Document对象中保存着整个xml文件中所有的元素节点
    18. Document doc=docb.parse("url");
    19. //4. 创建节点元素对象,并添加文本内容
    20. Element e=doc.createElement("节点元素名称");
    21. e.setTextContent("文本内容");
    22. //5. 依据节点元素的名称来获取节点元素,返回的是一个NodeList对象
    23. NodeList list= doc.getElementsByTagName("name");
    24. //6. 从NodeList对象中遍历获取节点元素Node对象
    25. for(int i=0;i<list.getLength();i++){
    26. Node node= list.item(i);
    27. //7. 通过Node对象来获取节点内的具体信息,或者进行增删改当前节点及子节点操作
    28. System.out.println(node.getTextContent());;//获取当前节点中的文本数据
    29. //8. 添加子节点
    30. node.appendChild(e);
    31. //删除当前节点
    32. /*
    33. Node parent=node.getParentNode();
    34. parent.removeChild(node);
    35. */
    36. }
    37. } catch (ParserConfigurationException e) {
    38. // TODO Auto-generated catch block
    39. e.printStackTrace();
    40. } catch (SAXException e) {
    41. // TODO Auto-generated catch block
    42. e.printStackTrace();
    43. } catch (IOException e) {
    44. // TODO Auto-generated catch block
    45. e.printStackTrace();
    46. }
    47. }
    48. }
  3. Document对象中数据的回写:当对xml文件解析成Document对象后,对Document对象进行修改后,需要回写到xml文件

    1. import java.io.IOException;
    2. import javax.xml.parsers.DocumentBuilder;
    3. import javax.xml.parsers.DocumentBuilderFactory;
    4. import javax.xml.parsers.ParserConfigurationException;
    5. import javax.xml.transform.Transformer;
    6. import javax.xml.transform.TransformerConfigurationException;
    7. import javax.xml.transform.TransformerException;
    8. import javax.xml.transform.TransformerFactory;
    9. import javax.xml.transform.dom.DOMSource;
    10. import javax.xml.transform.stream.StreamResult;
    11. import org.w3c.dom.Document;
    12. import org.w3c.dom.Node;
    13. import org.w3c.dom.NodeList;
    14. import org.xml.sax.SAXException;
    15. /**
    16. * @ClassName:Demo3
    17. * @Description:通过javax.xml.transform.Transformer类将内存中的树形结构的DOM数据回写到文件中进行保存
    18. */
    19. public class Demo3 {
    20. public static void main(String[] args) {
    21. try {
    22. DocumentBuilderFactory domfac=DocumentBuilderFactory.newInstance();
    23. DocumentBuilder docb=domfac.newDocumentBuilder();
    24. Document doc=docb.parse("url");
    25. NodeList list= doc.getElementsByTagName("name");
    26. //进行增删改修改元素节点,然后回写,比如修改某个节点的文本内容
    27. list.item(0).setTextContent("新文本内容");
    28. /*
    29. * 数据回写代码
    30. */
    31. //首先获取javax.xml.transform.Transformer类
    32. TransformerFactory transformerFactory=TransformerFactory.newInstance();
    33. Transformer trans=transformerFactory.newTransformer();
    34. //绑定要回写的Document对象
    35. DOMSource doms=new DOMSource(doc);
    36. //指定要回写到哪个xml文件中,参数写系统绝对路径或相对于当前类文件的相对路径
    37. //或者是一个File类型的对象,也可以是一个输出流对象
    38. StreamResult sr=new StreamResult("url");
    39. //进行回写
    40. trans.transform(doms, sr);
    41. } catch (ParserConfigurationException e) {
    42. // TODO Auto-generated catch block
    43. e.printStackTrace();
    44. } catch (SAXException e) {
    45. // TODO Auto-generated catch block
    46. e.printStackTrace();
    47. } catch (IOException e) {
    48. // TODO Auto-generated catch block
    49. e.printStackTrace();
    50. } catch (TransformerConfigurationException e) {
    51. // TODO Auto-generated catch block
    52. e.printStackTrace();
    53. } catch (TransformerException e) {
    54. // TODO Auto-generated catch block
    55. e.printStackTrace();
    56. }
    57. }
    58. }
  4. 对解析xml文件生成Document对象以及将Document对象进行回写封装可以成为一个工具类:

    1. import java.io.IOException;
    2. import javax.xml.parsers.DocumentBuilder;
    3. import javax.xml.parsers.DocumentBuilderFactory;
    4. import javax.xml.parsers.ParserConfigurationException;
    5. import javax.xml.transform.Transformer;
    6. import javax.xml.transform.TransformerConfigurationException;
    7. import javax.xml.transform.TransformerException;
    8. import javax.xml.transform.TransformerFactory;
    9. import javax.xml.transform.dom.DOMSource;
    10. import javax.xml.transform.stream.StreamResult;
    11. import org.w3c.dom.Document;
    12. import org.xml.sax.SAXException;
    13. /**
    14. * @ClassName:MyDomUtil
    15. * @Description:解析xml文件以及部分处理操作的封装类
    16. */
    17. public class MyDomUtil {
    18. //获取解析指定xml文件得到的Document对象
    19. public static Document readDocument(String url) throws ParserConfigurationException, SAXException, IOException{
    20. DocumentBuilderFactory domfac=DocumentBuilderFactory.newInstance();
    21. DocumentBuilder docb=domfac.newDocumentBuilder();
    22. Document doc=docb.parse(url);
    23. return doc;
    24. }
    25. //向磁盘中的文件回写Document对象中的数据,url指定文件所在的路径,doc指定要回写的Document对象
    26. public static void writeDocument(String url,Document doc) throws TransformerException{
    27. TransformerFactory fac=TransformerFactory.newInstance();
    28. Transformer trans=fac.newTransformer();
    29. DOMSource dom=new DOMSource(doc);
    30. StreamResult sr=new StreamResult(url);
    31. trans.transform(dom, sr);
    32. }
    33. }

    3. 通过JDK中的解析器以SAX方式进行XML文件解析的实现代码

    1. SAX原理:SAX采用事件处理的方式解析XML文件,主要是两个部分进行解析,分别是解析器和事件处理器。
    • 在创建解析器时,需要绑定一个事件处理器,该事件处理器类中的方法是对每一个标签进行处理的逻辑
    • 解析器每读到XML文件中某个标签的某一部分,都会调用事件处理器类中的某一个对应解析该部分的方法进行处理,将标签该部分的数据作为参数传入方法中,然后通过方法中的逻辑进行处理。
    • 事件处理器由可以使用默认的org.xml.sax.helpers.DefaultHandler类,但如果要实现自己的处理逻辑,就必须继承该类,然后重写其中的部分方法来实现自己的逻辑,获取标签数据并对数据进行处理。

注意,SAX方式解析xml文件不能对标签元素进行增删改操作,只能查询。

8c53f6951724fc6faad41b24a28e05a47a8.jpg

  1. 代码实现:

    1. import java.io.IOException;
    2. import javax.xml.parsers.ParserConfigurationException;
    3. import javax.xml.parsers.SAXParser;
    4. import javax.xml.parsers.SAXParserFactory;
    5. import org.xml.sax.Attributes;
    6. import org.xml.sax.SAXException;
    7. import org.xml.sax.helpers.DefaultHandler;
    8. /**
    9. * @ClassName:Demo4
    10. * @Description:以SAX方式解析xml文件
    11. */
    12. public class Demo4 {
    13. public static void main(String[] args) {
    14. try {
    15. //获取解析器
    16. SAXParserFactory fac=SAXParserFactory.newInstance();//解析器工厂
    17. SAXParser saxp=fac.newSAXParser();//解析器
    18. //解析XML文件,对于事件处理器需要由自己设计实现
    19. saxp.parse("url", new MyHandler());
    20. } catch (ParserConfigurationException e) {
    21. // TODO Auto-generated catch block
    22. e.printStackTrace();
    23. } catch (SAXException e) {
    24. // TODO Auto-generated catch block
    25. e.printStackTrace();
    26. } catch (IOException e) {
    27. // TODO Auto-generated catch block
    28. e.printStackTrace();
    29. }
    30. }
    31. }
    32. /**
    33. * @ClassName:MyHandler
    34. * @Description:重写事件处理器中部分方法逻辑,实现自己事件处理器类
    35. */
    36. class MyHandler extends DefaultHandler{
    37. /**
    38. * @Title:startElement
    39. * @Description:解析器解析xml文件中每一个标签的开始标签时(即<xx>),默认调用该方法,并把解析的内容传入方法参数
    40. * @param uri
    41. * @param localName
    42. * @param qName 标签名
    43. * @param attributes 标签中的所有属性
    44. * @throws SAXException
    45. * @see org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
    46. */
    47. public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
    48. // 在此处实现自己的处理逻辑
    49. System.out.println(qName);
    50. }
    51. /**
    52. * @Title:characters
    53. * @Description:解析器解析xml文件中的标签内的文本内容时),默认调用该方法将标签中的文本内容作为参数传入
    54. * @param ch
    55. * @param start
    56. * @param length
    57. * @throws SAXException
    58. * @see org.xml.sax.helpers.DefaultHandler#characters(char[], int, int)
    59. */
    60. @Override
    61. public void characters(char[] ch, int start, int length) throws SAXException {
    62. // 在此处实现自己的处理逻辑
    63. System.out.println(new String(ch));
    64. }
    65. /**
    66. * @Title:endElement
    67. * @Description:解析器解析xml文件中每一个标签的结束标签时(即</xx>),默认调用该方法,并把解析的内容传入方法参数
    68. * @param uri
    69. * @param localName
    70. * @param qName 标签名
    71. * @throws SAXException
    72. * @see org.xml.sax.helpers.DefaultHandler#endElement(java.lang.String, java.lang.String, java.lang.String)
    73. */
    74. @Override
    75. public void endElement(String uri, String localName, String qName) throws SAXException {
    76. // 在此处实现自己的处理逻辑
    77. System.out.println(qName);
    78. }
    79. }

    4. 通过Dom4J包来实现对XML文件的解析

首先,必须导入dom4j的包才能使用

1.解析:

  1. import java.util.List;
  2. import org.dom4j.Document;
  3. import org.dom4j.DocumentException;
  4. import org.dom4j.Element;
  5. import org.dom4j.io.SAXReader;
  6. public class Demo1 {
  7. public static void main(String[] args) {
  8. try {
  9. //获取解析器对象SAXReader,SAXReader是Dom4J包中SAX方式解析XML文件的类
  10. SAXReader sax=new SAXReader();
  11. //解析指定路径下的xml文件,获取该xml文件的Document对象
  12. Document doc=sax.read("url");
  13. //获取根节点,必须先获取根节点之后才能进行后续子标签的解析处理
  14. //Dom4J中解析xml文件,获取标签节点时,必须一层一层的获取,也就是说,必须先获取父节点,然后才是子节点
  15. Element root=doc.getRootElement();
  16. //获取子节点,并进行解析
  17. List<Element> list1=root.elements();//获取root节点下所有的直接子节点,并以集合形式返回
  18. List<Element> list2=root.elements("name");//获取root节点下所有的直接子节点中指定名称的节点,并以集合形式返回
  19. Element e=root.element("name");//获取root节点下所有的直接子节点中指定名称的第一个节点
  20. String text=e.getText();//获取标签节点内容
  21. } catch (DocumentException e) {
  22. // TODO Auto-generated catch block
  23. e.printStackTrace();
  24. }
  25. }
  26. }
  1. 实现节点元素的增删改:

    1. import java.io.FileOutputStream;
    2. import org.dom4j.Document;
    3. import org.dom4j.DocumentException;
    4. import org.dom4j.Element;
    5. import org.dom4j.io.OutputFormat;
    6. import org.dom4j.io.SAXReader;
    7. import org.dom4j.io.XMLWriter;
    8. public class Demo2 {
    9. public static void main(String[] args) throws Exception {
    10. //获取解析器对象
    11. SAXReader reader=new SAXReader();
    12. //解析获取XML文件的Document对象
    13. Document doc=reader.read("url");
    14. //获取根节点
    15. Element root=doc.getRootElement();
    16. //获取要修改的节点,在这个节点下添加一个子节点
    17. Element e=root.element("name");
    18. Element child=e.addElement("childname");//在这个节点下添加一个名为childname的子节点并返回这个子节点
    19. //设置文本内容
    20. child.setText("xxx");
    21. //回写,使用专用的一个流XMLWriter
    22. OutputFormat format=OutputFormat.createPrettyPrint();//如果使用该类,则输出到文件中后,会有对齐空格符
    23. format.setEncoding("utf-8");//设置文件编码
    24. XMLWriter writer=new XMLWriter(new FileOutputStream("目标文件路径"),format);
    25. writer.write(doc);
    26. writer.close();//关闭流
    27. }
    28. }

发表评论

表情:
评论列表 (有 0 条评论,682人围观)

还没有评论,来说两句吧...

相关阅读

    相关 XML文件

    现在解析XML的方法越来越多,但主流的方法也就四种,即:DOM、SAX、JDOM和DOM4J 下面首先给出这四种方法的jar包下载地址 DOM:在现在的Java JDK里

    相关 xml文件

    1. 解析方式 有两种解析方式,分别是: DOM:即Document Object Model,文档对象模型,W3C推出的专门用于解析xml一种处理方式 SAX:Sim...