[Java]_[初级]_[以SAX流的方式高效读取XML大文件]

场景

  1. XML文件作为默认utf8格式的文件,它的作用和JSON文件相当。比如可以做为简单的数据存储格式,配置文件,网站的sitemap.xml导航等。它比json强的一点是它还有样式描述文件dtd,可以实现让XML里的结构化数据显示表格样式。
<?xml version="1.0" encoding="UTF-8"?>
  1. sitemap.xml作为网站的站点地图,提供了固定的格式化数据, 也方便了搜索引擎进行索引。 因此对sitemap.xml的读写功能是比较重要的。那么如何实现大数据量的XML读写才可以节省内存和减少指令的执行?
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"xmlns:xhtml="http://www.w3.org/1999/xhtml"><url><loc>https://blog.csdn.net/infoworld</loc><priority>1.0</priority><lastmod>2023-07-28</lastmod><changefreq>Daily</changefreq></url>
</urlset>

说明

  1. JSON一样,对XML读用流的方式,可以减少中间的DOM模型的生成,也不需要读取整个XML文件到内存。这样的API不需要借助第三方库,Java标准库里就有。
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
  1. 流式读取使用SAX模型的方式,从开头按起始标签和结束标签的方式进行读取数据。并需要实现自己的Handler来处理需要的元素。这个Handler就是模板类,它的相关方法会在识别到XML特定的对象是调用,比如属性,起始结束元素,元素值等。
public boolean readAll(File file){SAXParserFactory sf = SAXParserFactory.newInstance();boolean result = false;try {SAXParser sp = sf.newSAXParser();sp.parse(file,this);logger.info(sitemaps.size()+"");result = true;} catch (ParserConfigurationException e) {logger.error(e.getMessage());} catch (SAXException e) {logger.error(e.getMessage());} catch (IOException e) {logger.error(e.getMessage());}return result;
}

例子

  1. 以下是读取sitemap.xml文件的Reader实现,Sitemap对象实际就是Map对象。

SitemapReader


import Sitemap;
import org.apache.log4j.Logger;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;public class SitemapReader extends DefaultHandler {private static Logger logger = Logger.getLogger(SitemapReader.class);private ArrayList<Sitemap> sitemaps = new ArrayList<>();private Sitemap current;private String cPValue;private String cPName;/*** 重置Reader,可以再次读取*/public void reset(){sitemaps.clear();cPName = null;cPValue = null;current = null;}/**** @return 读取到的sitemaps;*/public List<Sitemap> getSitemaps(){return sitemaps;}/**** @param file* @return*/public boolean readAll(File file){SAXParserFactory sf = SAXParserFactory.newInstance();boolean result = false;try {SAXParser sp = sf.newSAXParser();sp.parse(file,this);logger.info(sitemaps.size()+"");result = true;} catch (ParserConfigurationException e) {logger.error(e.getMessage());} catch (SAXException e) {logger.error(e.getMessage());} catch (IOException e) {logger.error(e.getMessage());}return result;}@Overridepublic void characters(char[] ch, int start, int length) throws SAXException {if(cPName != null && current != null) {cPValue = new String(ch, start, length);current.put(cPName,cPValue);}}@Overridepublic void endElement(String uri, String localName, String qName) throws SAXException {cPName = null;cPValue = null;switch(qName) {case "url": {sitemaps.add(current);current = null;break;}}}@Overridepublic void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {cPName = null;cPValue = null;switch(qName){case "url":{current = new Sitemap();break;}default:cPName = qName;}}
}

TestSitemapReader

import Sitemap;
import SitemapReader;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;import java.io.File;
import java.net.URL;
import java.util.List;
import java.util.logging.Logger;@RunWith(JUnit4.class)
public class TestSitemapReader{Logger logger = Logger.getLogger(TestSitemapReader.class.getName());@Testpublic void testXmlSaxReader(){URL resource = this.getClass().getResource("/");String path = resource.getPath();File file = new File(path+"..\\..\\..\\..\\doc\\tests\\xml\\sitemap.xml");SitemapReader sr = new SitemapReader();if(sr.readAll(file)){List<Sitemap> sitemaps = sr.getSitemaps();logger.info(sitemaps.size()+"");}}
}

参考

  1. SAX方式读取XML文件

  2. SAXParser

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/74114.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

OpenSSL加解密算法使用方法

下面简单记录一下 Linux上openssl命令的使用方法&#xff0c;包括 OpenSSL中加解密算法的使用方法和性能测试方法&#xff0c;以便让新手朋友们能快速用起来。持续更新中 … sm3算法 $ openssl sm3 /tmp/1.txt SM3(/tmp/1.txt) baafadbe43559b7043abd1682a4e12be05692cae175…

【QT】QMessageBox消息框的使用(16)

在实际项目中&#xff0c;弹出消息框是一个很常见的操作&#xff0c;包含错误信息提示、警告信息提示、关于信息提示、还包括判断信息选择等操作&#xff0c;那么今天通过这一节来好好了解下消息框的使用方法。 一.环境配置 1.python 3.7.8 可直接进入官网下载安装&#xf…

前端基础5——UI框架Layui

文章目录 一、基本使用二、管理后台布局2.1 导航栏2.2 主题颜色2.3 字体图标 三、栅格系统四、卡片面板五、面包屑六、按钮七、表单八、上传文件九、数据表格9.1 table模块常用参数9.2 创建表格9.3 表格分页9.4 表格工具栏9.5 表格查询9.5.1 搜索关键字查询9.5.2 选择框查询 9.…

记录窗体关闭位置(从窗体上次关闭的位置启动窗体)

从上次关闭位置启动窗体 基础类 using Microsoft.Win32; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Xml.Linq;namespace WindowsFormsApp1 {public class Reg{public static voi…

elementui图片上传转为base64字符串

场景&#xff1a;后端需要将上传的图片文件作为base64字符串的方式传参给他。 html代码 <div class"upload_box"><el-uploadclass"upload-demo"ref"upload"action"#":show-file-list"false":http-request"(f…

Mac电脑怎么使用NTFS磁盘管理器 NTFS磁盘详细使用教程

Mac是可以识别NTFS硬盘的&#xff0c;但是macOS系统虽然能够正确识别NTFS硬盘&#xff0c;但只支持读取&#xff0c;不支持写入。换句话说&#xff0c;Mac不支持对NTFS硬盘进行编辑、创建、删除等写入操作&#xff0c;比如将Mac里的文件拖入NTFS硬盘&#xff0c;在NTFS硬盘里新…

BGP路由属性

任何一条BGP路由都拥有多个路径属性&#xff08;Path Attributes&#xff09;&#xff0c;当路由器通告BGP路由给它的对等体时&#xff0c;该路由将会携带多个路径属性&#xff0c;这些属性描述了BGP路由的各项特征&#xff0c;同时在某些场景下也会影响BGP路由优选的决策。 一…

cudnn-windows-x86_64-8.6.0.163_cuda11-archive 下载

网址不太好访问的话,请从下面我提供的分享下载 Download cuDNN v8.6.0 (October 3rd, 2022), for CUDA 11.x 此资源适配 cuda11.x 将bin和include文件夹里的文件&#xff0c;分别复制到C盘安装CUDA目录的对应文件夹里 安装cuda时自动设置了 CUDA_PATH_V11_8 及path C:\Progra…

11 Python的正则表达式

概述 在上一节&#xff0c;我们介绍了Python的文件操作&#xff0c;包括&#xff1a;打开文件、读取文件、写入文件、关闭文件、文件指针移动、获取目录列表等内容。在这一节中&#xff0c;我们将介绍Python的正则表达式。正则表达式是一种强大的工具&#xff0c;用于在文本中进…

jvs-智能bi(自助式数据分析)9.1更新内容

​jvs-智能bi更新功能 1.报表增加权限功能&#xff08;服务、模板、数据集、数据源可进行后台权限分配&#xff09; 每个报表可以独立设置权限&#xff0c;通过自定义分配&#xff0c;给不同的人员分配不同的权限。 2.报表新增执行模式 可选择首次报表加载数据为最新数据和历…

怎样把英语视频字幕翻译成中文

我们知道&#xff0c;随着中外文化交流日益频繁&#xff0c;视频翻译作为一种重要的跨文化交流方式&#xff0c;也越来越受到重视。那么&#xff0c;怎样把英语视频翻译成中文&#xff0c;北京视频翻译哪里比较专业&#xff1f; 据了解&#xff0c;视频翻译是直接将一种语言的音…

报考浙江工业大学MBA项目如何选择合适的辅导班?

浙江工业大学MBA项目每年有数百人报考&#xff0c;在浙江省内除了浙大以外算是人数比较多的一个项目。2023级的招生中第一志愿也通过复试刷掉了百来人&#xff0c;在省内其实作为第一志愿报考的风险在逐渐增大&#xff0c;考生们如果坚持报考&#xff0c;则在针对联考初试的备考…

NJ求职盘点

电子显示 集成电路 地平线 后摩智能 芯启源 自动驾驶 地平线 栖霞区兴智科技园 泊车、SLAM/3D算法工程师 https://wecruit.hotjob.cn/SU64819a4f2f9d2433ba8b043a/pb/social.html?currentPage1 后摩智能 栖霞区兴智科技园 视觉感知算法资深工程师 可以做自动驾驶前瞻性…

建站系列(七)--- 常用前后端框架

目录 相关系列文章前言一、何为框架&#xff1f;二、为什么使用框架三、常用框架&#xff08;一&#xff09;Bootstrap&#xff08;二&#xff09;Layui&#xff08;三&#xff09;JQuery&#xff08;四&#xff09;Vue.js&#xff08;四&#xff09;ThinkPHP&#xff08;五&am…

deepin 如何卸载软件

文章目录 卸载软件&#xff08;正文&#xff09; 通常来讲在官方的应用商场卸载即可。 但是呢&#xff1f; 很不幸的是&#xff0c;没能够彻底删除软件。还是能够在启动器界面上看到应用。 这时候&#xff0c;你右键卸载&#xff0c;会提示“卸载失败”。如下图&#xff1a; …

SQL Server2022安装教程

SQL Server 是一个关系数据库管理系统。它最初是由Microsoft、Sybase 和Ashton-Tate三家公司共同开发的&#xff0c;于1988 年推出了第一个OS/2版本。在Windows NT 推出后&#xff0c;Microsoft与Sybase 在SQL Server 的开发上就分道扬镳了&#xff0c;Microsoft 将SQL Server移…

React16入门到入土

搭建环境 默认你已经安装好 node.js 安装 react 脚手架 学习的过程中&#xff0c;我们采用React官方出的脚手架工具 create-react-app npm install -g create-react-app如果提示没有权限&#xff0c;win 用户可以管理员打开终端&#xff0c;mac 用户 可以在前面加上 sudo …

滑动窗口的最大值(双端队列,单调队列)

力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 class Solution {public int[] maxSlidingWindow(int[] nums, int k) {LinkedList<Integer> deque new LinkedList<>();//双端队列&#xff0c;存储单调队列的下标int ans[] new int[nu…

公开游戏、基于有向图的游戏

目录 〇&#xff0c;背景 一&#xff0c;公开游戏、策梅洛定理 1&#xff0c;公开游戏 2&#xff0c;策梅洛定理 二&#xff0c;有向图游戏 1&#xff0c;狭义有向图游戏 2&#xff0c;广义有向图游戏 3&#xff0c;狭义有向图游戏的SG数 4&#xff0c;Bash Game 力扣…

LVGL Animations(动画)的简单使用

一、前言 哈喽&#xff0c;大家好。在进行界面设计的时候&#xff0c;动画的使用是必不可少的&#xff0c;今天这篇文章就跟大家分享一下 LVGL Animations&#xff08;动画&#xff09;的简单使用。笔者将在模拟器上运行演示&#xff0c;LVGL 版本号为 8.3.0。 二、Animation…