用Java如何处理XML数据

Java原生内置的处理XML的技术基本有这么几种:DOM,SAX,Stax,Jaxb.那么用Java我们要如何处理XML数据,希望对大家有帮助!

DOM :Document Object Model 顾名思义就是在内存中构建树形结构。处理小的XML文件还算勉强应付。如果文件比较大,他需要一次性装载整个XML,你会忍不了他的速度,并且他会吃光你所有的内存,最后程序会负分滚粗。

SAX:Simple API for XML Parsing 一般名字应该是没实现的愿望体现。比如一个人如果叫王金库,那么可以肯定他绝对没有金库。这样你应该理解这个API为啥叫Simple了。这API是回调式的,也就是你写的程序是被别人调戏用的。这API比DOM快点,而且是可以部分装载XML,这样你不用害怕OOME了。啥?你想写XML?忘掉这个叫Simple的玩意儿吧。

Stax: Streaming API for XML 这个总算是靠点谱了。你写的程序是主动式的访问XML各个节点。流式访问,不用担心OOME,速度嘛算是原生态里面最好的了。而且读写都支持,你不用这个还用哪个啊?

给个Stax的代码片段,算是参考吧:

XMLInputFactory xif = XMLInputFactory.newInstance();

XMLStreamReader xsr = xif.createXMLStreamReader(new FileReader("input.xml"));

xsr.nextTag(); // Advance to statements element

long i = 0;

String action = null;

while (xsr.hasNext()) {

if (xsr.next() == XMLStreamConstants.START_ELEMENT) {

if ("ContentItem".equals(xsr.getLocalName())) {

action = getAttributeValue(xsr, "action");

} else if ("Data".equals(xsr.getLocalName())) {

i ++;

}

}

}

JAXB:Java Architecture for XML Binding 这是一个很酷的API.想法就是把XML各种属性定义映射到普通的Java Bean上。你无须关心解析反解析的细节,只要用普通的Java Bean就完成和XML的交互了。可是怎么构建一一映射的JavaBean呢?在已知XML的定义的情况下你可以用自带的xjc 命令自动生成相对应的JavaBean.如果你用Eclipse,有类似的插件帮你完成这步。具体可以google一下。然后你要做的就是仅仅是使用数据啦。简单的令人发指:

JAXBContext jc = JAXBContext.newInstance("com.your.xml.datatype.bean"); // 先注册你的JavaBean

// Create unmarshaller

Unmarshaller um = jc.createUnmarshaller();

// Unmarshal XML contents of the file myDoc.xml into your Java object

// instance

ObjectFactory objFac = new ObjectFactory(); // 生成Bean之后你会有这个工厂类的

objFac.createYourData(objFac.createYourDataType());

BufferedInputStream bis = new BufferedInputStream(new FileInputStream("your.xml")); // 你要怎么打开你的'XML文件呢?

JAXBElement myJAXBObject = (JAXBElement) um.unmarshal(bis); // 读取

YourDataType yourData = (YourDataType) myJAXBObject.getValue(); // 可以用啦

// 下面是写XML的例子

Marshaller m = jc.createMarshaller();

m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);

File outfile = new File("yourOutput.xml");

BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(outfile), 4096);

m.marshal(myJAXBObject, bos); // 一步写入。 myJAXBObject 需要你自己构建,你要存什么呢

try {

bos.flush();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} finally {

try {

bos.close();

} catch (Exception e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

你也许意识到问题了:这一下子把XML Load到内存里,你是不是疯了?为了避免疯掉,你可以用Satx啊,那玩意儿不是流式的么?给个栗子,读取这样的XML文件片段:

private static void readWriteWithStAXAndJAXB() throws FactoryConfigurationError, FileNotFoundException, XMLStreamException, UnsupportedEncodingException, JAXBException,

PropertyException {

// set up a StAX reader

XMLInputFactory xmlif = XMLInputFactory.newInstance();

BufferedInputStream bis = new BufferedInputStream(new FileInputStream("inputLarge.xml"));

XMLStreamReader xmlr = xmlif.createXMLStreamReader(bis);

File outfile = new File("output\outfile.xml");

OutputStreamWriter bos = new OutputStreamWriter(new FileOutputStream(outfile), "UTF-8");

XMLOutputFactory xmlof = XMLOutputFactory.newInstance();

XMLStreamWriter xmlw = xmlof.createXMLStreamWriter(bos);

xmlw.writeStartDocument("UTF-8", "1.0");

xmlw.writeStartElement("OutXMLData");

JAXBContext ucontext = JAXBContext.newInstance(SubXMLItemType.class);

Unmarshaller unmarshaller = ucontext.createUnmarshaller();

Marshaller marshaller = ucontext.createMarshaller();

marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);

marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);

xmlr.nextTag();

xmlr.require(XMLStreamConstants.START_ELEMENT, null, "OutXMLData");

xmlr.nextTag();

int iCount = 0;

while (xmlr.getEventType() == XMLStreamConstants.START_ELEMENT) { // 按标签流式读取

iCount++;

JAXBElementpt = unmarshaller.unmarshal(xmlr, SubXMLItemType.class); // 只读取映射SubItem的内容

marshaller.marshal(pt, xmlw); // 这步是分批流式写入

xmlw.writeCharacters(" ");

if (xmlr.getEventType() == XMLStreamConstants.CHARACTERS) {

xmlr.next();

}

}

xmlw.flush();

xmlw.writeEndElement();

xmlw.writeEndDocument();

System.out.println("Entity Count is :" + iCount);

xmlr.close();

xmlw.close();

}

说完这么多,基本上用Java处理XML已经不是难事了。不过,有时候你会有:给你蟹八件儿,你也无从下嘴的感受。比如,解析XML你可以掌控,随便你用啥,可是你调用的下游程序接口却需要另外一种格式的数据。比如,你用Stax解析XML,下游要DOM接口会不会令你抓狂起来?心里咒骂,倒霉玩意儿,你们还有没有点上进心?!最近我就遇到这事了,解析一个大的XML,下游要Sub的XML,或者叫XML片段,或者叫分割XML文件。好么,我把数据都拆成Java的Object,然后再给你拼成一个个小的XML文件发过去,丧心病狂么这不?!你如果真这么做了,就别往下看了,你会哭的!

Java 的XML包下面有个transform的子包,看看里面会有惊喜的。可以用这个工具包帮你完成类似的转换,比如Stax 和 Sax 或者Dom 互相的变换。或者变换成Stream.

拿我这个分割XML的小栗子来说:

XMLInputFactory xif = XMLInputFactory.newInstance();

XMLStreamReader xsr = xif.createXMLStreamReader(new FileReader("input.xml")); // 用Stax读取XML

xsr.nextTag(); // Advance to statements element

TransformerFactory tf = TransformerFactory.newInstance();

Transformer t = tf.newTransformer();

t.setParameter(OutputKeys.OMIT_XML_DECLARATION, "no");

t.setParameter(OutputKeys.STANDALONE, "yes");

long i = 0;

String action = null;

while (xsr.hasNext()) {

if (xsr.next() == XMLStreamConstants.START_ELEMENT) {

if ("ContentItem".equals(xsr.getLocalName())) {

action = getAttributeValue(xsr, "action");

} else if ("Data".equals(xsr.getLocalName())) {

File file = new File("out/" + action + i++ + ".xml");

t.transform(new StAXSource(xsr), new StreamResult(file)); // 流式变换,走你~

// DOMResult dr = new DOMResult(); // 如果你要Dom格式的,releaseMe

// t.transform(new StAXSource(xsr), dr);

}

}

}

知道最变态的是什么吗?需要解析XML整个内容到String里面,不单单是数据,就是整个XML标签和数据。其实就是ouputStream转String的过程:

ByteArrayOutputStream baos = new ByteArrayOutputStream();

t.transform(new StAXSource(xsr), new StreamResult(baos));

String subXMLStr = baos.toString();

【用Java如何处理XML数据】相关文章:

java操作xml一般都用什么_用Java如何处理XML数据相关推荐

  1. java 操作mysql数据库得到错误码_[数据库/Java]数据库开发过程中产生的MySQL错误代码及其解决方案...

    前言 吐槽一下,均是这两天遇到的破烂事儿,搞定了也好,以后出现此类问题也就放心些了. 下列遇到的问题大都是因为MySQL从5.x版本升级到8.0.11(MySQL8.0涉及重大改版)后,跟着连带着出现 ...

  2. java传统的项目有哪些内容_请问java全套内容都有什么呢?

    我整理的Java全套内容学习路线,分为6个阶段(大阶段)第一阶段:java内功心法篇 第二阶段:Java武功秘籍(经典框架) 第三阶段:Java高级功法(主流框架) 第四阶段:Java成神之路 第五阶 ...

  3. java技术文章在哪里看呢_谈论Java技术似乎无处不在,但究竟是什么呢?文章末尾有福利...

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 谈论Java技术似乎无处不在,但究竟是什么呢? 下面的部分将解释Java技术如何既是一种编程语言,又是一种平台,并概述这种技术可以为您做些什么. Java ...

  4. java简单通讯录的实现02person类_用java实现简单的小游戏(你一定玩过)

    用java实现简单的小游戏(你一定玩过) 对于java初学者来说,通过一些学习小游戏来对swing学习以及对java基础的学习是一个好的方法,同时也给学习带来了很多的乐趣,接下来就给大家分享一个jav ...

  5. Java程序员从笨鸟到菜鸟之(一百零四)java操作office和pdf文件(二)利用POI实现数据导出excel报表...

    在上一篇博客中,我们简单介绍了java读取word,excel和pdf文档内容 ,但在实际开发中,我们用到最多的是把数据库中数据导出excel报表形式.不仅仅简单的读取office中的数据.尤其是在生 ...

  6. java代码嵌入html代码是什么_用java给html文件添加必要的控制html代码片

    这个需求,我估计很多时候都不会用到,但是,我们目前在做一个CMS的系统,在创建页面的时候,需要控制页面各个板块显示的内容来源,这个不是关键,关键是页面内容配置完毕后,如何提交内容,也就是说如何和后台系 ...

  7. java 中的finally你知多少_「JAVA」详述Java异常体系,处理异常时配上finally效果更佳...

    什么是异常 从事Java开发的小伙伴对于"异常"应该不陌生,因为每天都会遇到不少异常,或捕获,或抛出.那究竟什么是异常?异常即非正常的,不同于平常.一般化的情况.在平时生活中,医生 ...

  8. java写一段程序代表心情_讨论java初步学习的方法及心情

    Java的重要性 Java语言的三大特点,面向对象.良好的跨平台性和健壮性,这三大特点使Java被广大编程人员接收并且使用.Java的核心机制有Java虚拟机和垃圾回收机制这两种,Java虚拟机通过解 ...

  9. java基础不好框架能学会吗_转行Java能学会吗?零基础学习Java的学习路线

    Java的跨平台性.通用性.安全性.高效性决定了这门语言在未来10年都会是最热门的语言之一.Java技术的安全性和平台移植性足够让他应用到不同的领域,它的工作需求足够大,现实一点来说即使Java濒临o ...

最新文章

  1. 【1】 pythonic modern c++:字符串
  2. TZOJ--3560: Ordered Fractions (枚举)
  3. Linux用extundelete恢复磁盘文件-攻防世界Recover-Deleted-File
  4. c语言圈子,C语言经典编程
  5. 查找目录下的及子目录下的 所有的给定后缀名的文件并将其路径打印到一个文件中。
  6. python入门小程序代码_Python入门小程序(二)
  7. python之路---15 装饰器
  8. linux6.4添加源,RHEL6.4更改为CentOS源
  9. xjad一款不错的java反编译软件
  10. python 谷歌翻译
  11. Excel论文画折线图
  12. 记录贴:学习Andorid开发
  13. 2W+字系统讲解如何用Python自动化操作PPT,学懂这篇文章就够了
  14. 资产监测设备中,使用浏览器解码Sigfox上行负载
  15. Mysql数据库计算时间差(天,时,分,秒)
  16. 那些创新是如何产生的?
  17. [附源码]Python计算机毕业设计Django自行车租赁管理系统
  18. 微信小程序生成小程序二维码图片无法正常显示的问题
  19. QT开发之调用其它类中的UI控件的方法
  20. SOP和WI有什么区别?

热门文章

  1. Mac adb 安装
  2. 潭州Java中级班(day_13)-异常概述
  3. 洛谷 P1890 gcd区间
  4. HDU 1114 iggy-Bank(完全背包)
  5. 智能家居系统--选配防盗锁新(转载)
  6. shell判断文件,目录是否存在或者具有权限 (转载)
  7. 深入理解linux网络技术内幕读书笔记(十)--帧的接收
  8. [转载]网站分析的最基本度量(3)——网站分析工具如何辨别UV
  9. meta几个常用的地方
  10. Windows Phone7 手机越狱教程