XML解析之ajxp

本文介绍了XML的两种主要解析方式:DOM和SAX。DOM在内存中构建XML树形结构,便于增删改查,但可能因文件过大导致内存溢出;SAX采用事件驱动逐行解析,适用于大文件查询,但不支持增删改。文章还详细说明了如何使用JAXP进行查询、添加、修改和删除操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

XML 的解析简介

解析方式dom和sax
- dom方式解析
- 根据XML层级结构,在内存中分配一个树形结构,把xml标签,属性,文本封装成对象
- 缺点:如果文件过大,造成内存溢出
- 优点:很方便增删改查
- sax方式解析:
- 采用事件驱动,边度边解析,从上到下一行一行的解析,解析到一个对象,返回对象名
- 缺点:不能实现增删改操作
- 优点:如果文件过大不会造成内存溢出,方便实现查询操作

这里写图片描述

  • 要想解析XML,首先需要解析器
    • 不同的公司和组织提出了针对dom和sax方式的解析器,通过api方式提供
    • sun公司针对dom和sax提供了:jaxp
    • dom4j组织陈对dom和sax提供了:dom4j
    • jdom组织针对dom和sax提供了:jdom

jaxp的api查看

  • jaxp是Javase的一部分:在javax.xml.parsers包下,常用的有4个类
  • 针对dom的类
    • DocumentBuilder这是一个抽象类,解析器,这个类的 实例是通过DocumentBuilderFactory.newDocumentBuilder()方法获取的。
      • parse(File f)将传入的文件解析
      • parse(String uri)根据传入文件的索引解析
    • DocumentBuilderFactory解析器工厂
  • 针对sax 的类
    • SAXParser
    • SAXParserFactory

jaxp 的应用

  • 使用jaxp查询节点

    • 使用解析器工厂创建解析器
    • 使用解析器的解析方法获得document对象
    • 使用dom对象的方法赛选节点返回一个节点数组
    • 使用for循环遍历
      
      
      import javax.xml.parsers.DocumentBuilder;
      import javax.xml.parsers.DocumentBuilderFactory;
      
      import org.w3c.dom.Document;
      import org.w3c.dom.Node;
      import org.w3c.dom.NodeList;
      
      public class Demo1 {
          public static void main(String[] args) throws Exception {
      //      使用解析器工厂创建 解析器
              DocumentBuilderFactory instance = DocumentBuilderFactory.newInstance();
              DocumentBuilder document = instance.newDocumentBuilder();
      //      使用解析器的解析方法解析xml
              Document parse = document.parse("src\\haha.xml");
      //      指定要解析的元素
              NodeList list = parse.getElementsByTagName("name");
      //      遍历节点
              for (int i = 0; i < list.getLength(); i++) {
      //          获得节点
                  Node item = list.item(i);
      //          查看节点的内容
                  String text = item.getTextContent();
      //          打印节点内容
                  System.out.println(text);
              }
          }
      }
      
      
  • 给xml文件中添加某一个节点

    • 获得要添加节点的父节点来进行操作
    • 创建要添加的 节点和内容
    • 把要添加的节点和节点内容建立联系,把要添加的节点和符节点建立联系
    • 解析的操作都是在内存层面的,所以需要 使用Transformer类的transform(Source xmlSource, Result outputTarget) 方法进行回写到源文件

      
              /**
           * 给XML文件中添加一个节点name
           * @author lien
           * @return void
           * @throws Exception 
           * 
           * */
          public static void add() throws Exception {
              DocumentBuilderFactory newInstance = DocumentBuilderFactory.newInstance();
              DocumentBuilder newDocumentBuilder = newInstance.newDocumentBuilder();
              Document parse = newDocumentBuilder.parse("src\\haha.xml");
      //      获得了要操作的父节点
              Node item = parse.getElementsByTagName("author").item(0);
      //      创建一个要添加的子节点
              Element createElement = parse.createElement("name");
              Text createTextNode = parse.createTextNode("李恩");
      //      将创建的节点和内容建立联系
              createElement.appendChild(createTextNode);
      //      将创建的节点和父节点建立联系
              item.appendChild(createElement);
      
              /*
               *  因为我们这里的操作知识对内存中的xml进行解析
               *  所以还需要进行回写才能在xml文件显示我们添加的节点
               *  这里需要使用的是Transforme类,请查看api文档
               * */
              //通过使用TransformerFactory工厂获得Transform实例
              TransformerFactory newInstance2 = TransformerFactory.newInstance();
              Transformer newTransformer = newInstance2.newTransformer();
              //回写操作,这种方式可以 添加,但是 格式不正常,不建议使用
              newTransformer.transform(new DOMSource(parse), new StreamResult("src\\haha.xml"));
      
      
          }
    • 缺点:使用 这种方式 添加修改等操作,xml格式会很乱的.例如:下图中添加的节点name,显示格式很乱。
      这里写图片描述

  • 修改操作
    • 将一个子节点中的内容修改为自己想要的,基本操作和添加相同
    • 只是使用了setTextContent(String)方法设置了内容
    • 一定要回写操作

      /**
      <ul><li>修改一个节点的内容</li>
      <li>@author lien</li>
      <li>@return void</li>
      <li>@throws Exception </li>
      <li>
      <ul><li>*/
      public static void alter() throws Exception {
      DocumentBuilderFactory instance = DocumentBuilderFactory.newInstance();
      DocumentBuilder documentBuilder = instance.newDocumentBuilder();
      Document document = documentBuilder.parse("src\\haha.xml");
      Node node = document.getElementsByTagName("name").item(0);
      node.setTextContent("张学友");
      //回写操作
      TransformerFactory factory = TransformerFactory.newInstance();
      Transformer transformer = factory.newTransformer();
      transformer.transform(new DOMSource(document), new StreamResult("src\\haha.xml"));
      }
  • 删除节点,使用了document的removeChile(Node)方法,写 回写操作
  • 替换节点,使用了document的replaceChild(Node newChile,Node oldChild)方法,写回写操作
  • 遍历节点操作

                /**
         * 遍历操作
         * @author lien
         * @throws IOException 
         * @throws SAXException 
         * @throws ParserConfigurationException 
         * */
        public static void dump(Node document) {
            if(document.getNodeType() == Node.ELEMENT_NODE) {
    //          xmL中的所有空格换行都被当作节点 处理,所以判断如果是一个元素节点再打印
                System.out.println(document.getNodeName());
    
            }
            NodeList nodes = document.getChildNodes();
    //      遍历节点集合
            for(int i = 0 ;i < nodes.getLength(); i++) {
                Node item = nodes.item(i);
                dump(item);
            }
    
        }
  • ajxp针对sax的解析

    • 事件驱动,边读边解析,主要是两个类
    • sax不能实现增删改操作,主要是查询操作
    • SAXparser 解析器,
      • parse(String uri, DefaultHandler dh)方法解析
        • url 要解析的文件 地址
        • DefaultHandler 事件处理器,一半要创建一个类继承这个事件处理器重写三个方法,这样可以实现输出的功能等等;
    • SAXpsrserFactory 解析器工厂
    • sax解析过程

      • 当解析到开始标签的时候,会自动执行startElement方法
      • 当解析到结束标签的时候,会自动执行 endElement方法
      • 当解析到文本的时候,会自动执行characters方法,

      • 这里写图片描述

    • 实例:使用sax方式解析xml,遍历所有的元素,并且打印输出这里写图片描述
    • 实例:使用sax方式解析xml,遍历指定的标签的内容

          /*
       * 使用sax方式解析,获取 标签name的值
       * 
       * */
      public static void pars() throws Exception {
          SAXParserFactory instance = SAXParserFactory.newInstance();
          SAXParser parser = instance.newSAXParser();
          parser.parse("src\\haha.xml", new MyDefaultHandler1());
      }
      
           //定义了一个事件处理器重写了 三个方法,为了方便输出
      class MyDefaultHandler1 extends DefaultHandler{
          boolean flag = false;
          @Override
          public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
              super.startElement(uri, localName, qName, attributes);
              if("name".equals(qName)) {
                  flag = true;
              }
          }
      
          @Override
          public void endElement(String uri, String localName, String qName) throws SAXException {
              super.endElement(uri, localName, qName);
              flag = false;
          }
      
          public void characters(char[] ch, int start, int length) throws SAXException {
              super.characters(ch, start, length);
              if(flag == true) {
      
                  System.out.println(new String(ch,start,length));
              }
          }
      
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值