手写 HTTP 服务器中涉及到的 XML 解析相关知识

1. XML 相关简单介绍:

XML 是一种通用的数据交换格式,无关平台语言系统,在 Java 项目中 XML 作为一种常见的配置文件,我们肯定是需要去解析它的。

XML 包含的内容有:

  • DOM(Document Object Model)
  • DTD (Document Type Definition)
  • SAX(Simple API for XML)
  • XSD (XML Schema Definition)

XML 在不同语言中解析的方式一样,只是实现的语法不同,基本解析方式有两种:SAXDOM

2. Java 中解析 XML 的对应实现类

2.1 DOM

提供者:W3C

特点:一次性读取 XML,将其内容构建为 树型结构 保存在 内存 中。

  • 优点: 整个文档都被读入内存,方便操作,支持删除、修改、重新排列等功能
  • 缺点: 浪费空间,查找无用节点时浪费时间

适用场景:需要多次访问 XML 文档数据,并且硬件资源充足、

2.2 SAX

特点: 流式读取,边读取边解析。占用内存小,以事件回调的方式让调用者获取数据。

SAX 对应的回调事件:

这些事件被定义在 DefaultHanlder 这个类中。

  • startDocument ---> 开始读取 XML 文档
  • startElement ---> 读取到了一个元素 例如 <xxx>
  • characters ---> 读取 元素之间的内容
  • endElement ---> 读取到了元素的结束 例如 </xxx>
  • endDocument ---> XML 文档读取结束

我们通过这几个事件就可以读取 XML 文档了。

演示代码:

1、首先编写一个类继承 DefaultHanlder ,来对上面的回调事件进行相应的处理


class PHandler extends DefaultHandler {
    @Override
    public void startDocument() throws SAXException {
        System.out.println("开始解析文档");
    }

    // 解析 XML 标签,解析 XML 元素

    /**
     * @param uri
     * @param localName
     * @param qName 标签名
     * @param attributes
     * @throws SAXException
     */
    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes)
            throws SAXException {
        System.out.println(qName + "解析开始");
    }


    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        // 去掉空格
        String contents = new String(ch, start, length).trim();
        if (contents.length() > 0) {
            System.out.println("内容为" + contents);
        } else {
            System.out.println("内容为-->空");
        }
    }

    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        System.out.println(qName + "解析结束");
    }

    @Override
    public void endDocument() throws SAXException {
        System.out.println("解析文档结束");
    }

}

2、编写对应的测试代码:

public class XmlTest {
    public static void main(String[] args)
            throws ParserConfigurationException, SAXException, IOException {
        // 1、获取解析工厂
        SAXParserFactory factory = SAXParserFactory.newInstance();
        // 2、从解析工厂获取解析器
        SAXParser parse = factory.newSAXParser();
        // 3、加载文档 Document处理器
        PHandler handler = new PHandler();
        // 4、使用对应处理器解析XML文档
        parse.parse(Thread.currentThread().getContextClassLoader()
                .getResourceAsStream("study01/server/basic/servlet/web.xml"), handler);
    }
}

测试 XML:

<?xml version="1.0" encoding="UTF-8"?>
<web-app>
    <servlet>
        <servlet-name>login</servlet-name>
        <servlet-class>study03.LoginServlet</servlet-class>
    </servlet>
    <servlet>
        <servlet-name>reg</servlet-name>
        <servlet-class>study03.RegisterServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>login</servlet-name>
        <url-pattern>/login</url-pattern>
        <url-pattern>/g</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>reg</servlet-name>
        <url-pattern>/reg</url-pattern>
    </servlet-mapping>
</web-app>

解析结果:

image-20201027003806074

Q.E.D.

知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议

最是人间留不住,曾是惊鸿照影来。