java-XML
XML不再多说,XML 约束也不用说了,这里讲讲java如何对XML操作。
java中使用XML,目前常用的就是Jaxp(sun)和dom4j了,这里先讲讲java自带的Jaxp包
Jaxp的xml解析器有两种,一种是DOM解析器,一种是SAX解析器,两种各自应用在不同的场景上。
在DOM解析时,会把xml中各个节点视为对象,然后根据父子关系相互嵌套。优点时容易操纵,缺点也很明显,必须全部通读xml并加载进内存。
DOM解析的流程:
1,DocumentBuilderFactory是抽象类,newInstance()方法会根据本地平台安装的xml解析器自动创建相应的工厂实力
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); |
2,DocumentBuilder的newDocumentBuilder()方法会得到本地xml解析器相应的DocumentBuilder实力
DocumentBuilder documentB = dbf.newDocumentBuilder(); |
3,解析xml,根据DocumentBuilder的parse方法。
Document document = documentB.parse( new File(path)); //看文档可以知道,parse可以从解析File、InputSource(经过包装的InputStream)、InputStream和URI字符串 |
4,Document代表了整个XML文档,首先获取根节点,Element就是标签,它们都属于Node,也就是说,都实现了Node接口
Element root=document.getDocumentElement(); |
5,下面就是增删改查了
增加结点
//增加一个结点,注意,增加节点是对document操作,Document实现了这个方法 Element newStudent=document.createElement( "student" ); //增加一个属性,属性也算是结点,一切都是Node Attr cid=document.createAttribute( "idcard" ); //给属性设置值 cid.setValue( "1121" ); //将属性添加进这个标签 newStudent.setAttributeNode(cid); //最后,将这个结点添加进根节点,注意,是对根节点添加,不是Document root.appendChild(newStudent); |
提取某节点信息(查)
//首先根据第3步,已经获得根结点,也就是Element root //获取所有标签名为sutdent的节点集合 NodeList students=root.getElementsByTagName( "student" ); //至于获取标签属性以及text内容,自行看手册 //要注意的是,换行和制表符'\n\t'这些,也会被当做text内容解析 //至于xml的编码问题,都是自动的,不用手动设置了。 |
更改结点内容(很多都是Node接口的方法,自行查看手册即可)
//设置标签内容 Node.setTextContent(String text) //设置属性内容 Attr.setValue(String value) |
删除结点
Node.removeChild(Node node) |
6,操作完xml,保存结果
//1、获得Transformer工厂 TransformerFactory tff=TransformerFactory.newInstance(); //2、对于DOM对象,使用树来表示,肯定是个多叉树了,,, //这个类,就是将树,变为结果树 Transformer tf = tff.newTransformer(); //3、把document(DOM)转换为xml source Source sc= new DOMSource(document); //4、创建一个DOM目标,这里是个流 Result rs= new StreamResult( new File(path_URI)); //5、将 XML Source 转换为 Result,这样就写入数据流了 tf.transform(sc, rs); |
DOM解析就到这里,如果以网络流读取一个大的xml文件的话,这样肯定是不行的,不可能一直等到它全部读完载入内存再操作吧。。。。。光读取的话,就用SAX了。
事件处理器由程序员编写,程序员通过事件处理器中方法的参数,就可以很轻松地得到sax解析器解析到的数据,从而可以决定如何对数据进行处理
我们常用的就是ContentHandler了。
下面是sax示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | //定义工厂api,用以配置和获取sax解析器 SAXParserFactory spf = SAXParserFactory.newInstance(); //得到解析器对象 SAXParser sp = spf.newSAXParser(); //得到一个xmlreader读取器 XMLReader xmlReader = sp.getXMLReader(); //注册一个内容事件处理器 ContentHandler,一般情况下,使用ContentHandler接口的已知 //子类DefaultHandler就行了 xmlReader.setContentHandler( new DefaultHandler(){ //为了方便,以内部类重写需要使用到的方法 //开始读取标签 public void startElement(String uri, //命名空间 String localName, //标签名 String qName, //限定名称 Attributes attributes //属性 ){ /////////////////////////// //获取标签的个数 attr.getLength(); //其它的看手册 } //开始读取文档 public void startDocument(){ } //读取到标签尾 public void endElement( String namespaceURI, String localName, String qName ) { } //读取标签体,注意的是,sax是分段读取的,每次最大读取是2kb public void characters( char [] ch, int start, int length ){ //读取大数据的时候注意sax是分段读取的,每次最大读取是2kb } }); //开始读取xml数据 xmlReader.parse( "book.xml" ); |
到这里,我们发现SAX虽然比DOM效率高,但是它是顺序读取的,无法回头,且只能从头到尾。
现在就可以使用Dom4j了,它是第三方包
//1.读取XML文件,获得document对象 SAXReader reader = new SAXReader(); Document document = reader.read( new File( "input.xml" )); //2.解析XML形式的文本,得到document对象. String text = "<members></members>" ; Document document = DocumentHelper.parseText(text); //3.主动创建document对象. Document document = DocumentHelper.createDocument(); //创建根节点 Element root = document.addElement( "members" ); |
dom4j 中结点对象的操作:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | //1.获取文档的根节点. Element root = document.getRootElement(); //2.取得某个节点的子节点. Element element=node.element(“书名"); //3.取得节点的文字 String text=node.getText(); //4.取得某节点下所有名为“member”的子节点,并进行遍历. List nodes = rootElm.elements( "member" ); for (Iterator it = nodes.iterator(); it.hasNext();) { Element elm = (Element) it.next(); // do something } //5.对某节点下的所有子节点进行遍历. for (Iterator it=root.elementIterator();it.hasNext();){ Element element = (Element) it.next(); // do something } //6.在某节点下添加子节点. Element ageElm = newMemberElm.addElement( "age" ); //7.设置节点文字. element.setText( "29" ); //8.删除某节点. //childElm是待删除的节点,parentElm是其父节点 parentElm.remove(childElm); //9.添加一个CDATA节点. Element contentElm = infoElm.addElement( "content" ); contentElm.addCDATA(diary.getContent()); |
对节点对象属性的操作:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | //1.取得某节点下的某属性 Element root=document.getRootElement(); //属性名name Attribute attribute=root.attribute( "size" ); //2.取得属性的文字 String text=attribute.getText(); //3.删除某属性 Attribute attribute=root.attribute( "size" ); root.remove(attribute); //4.遍历某节点的所有属性 Element root=document.getRootElement(); for (Iterator it=root.attributeIterator();it.hasNext();){ Attribute attribute = (Attribute) it.next(); String text=attribute.getText(); System.out.println(text); } //5.设置某节点的属性和文字. newMemberElm.addAttribute( "name" , "sitinspring" ); //6.设置属性的文字 Attribute attribute=root.attribute( "name" ); attribute.setText( "sitinspring" ); |
在指定位置中插入元素:
//Element元素可以通过DocumentHelper对象得到。示例代码: Element aaa = DocumentHelper.createElement( "aaa" ); aaa.setText( "aaa" ); List list = root.element( "书" ).elements(); list.add( 1 , aaa); |
写入XML文档
//1.文档中全为英文,不设置编码,直接写入的形式. XMLWriter writer = new XMLWriter( new FileWriter( "output.xml" )); writer.write(document); writer.close(); //2.文档中含有中文,设置编码格式写入的形式.OutputFormat format = OutputFormat.createPrettyPrint();// 指定XML编码 format.setEncoding( "GBK" ); XMLWriter writer = new XMLWriter(newFileWriter( "output.xml" ),format); writer.write(document); writer.close(); |
XML与字符串的转换
//1.将字符串转化为XML String text = "<members> <member>sitinspring</member></members>" ; Document document = DocumentHelper.parseText(text); //2.将文档或节点的XML转化为字符串. SAXReader reader = new SAXReader(); Document document = reader.read( new File( "input.xml" )); Element root=document.getRootElement(); String docXmlText=document.asXML(); String rootXmlText=root.asXML(); Element memberElm=root.element( "member" ); String memberXmlText=memberElm.asXML(); |
在Dom4j中使用xpath查询路径
xpath路径表达式就像正则表达式一样,可以免去自己写遍历对比代码了。
//dom4j的包中的document.......... List<Node> list = document.selectNodes( "//xpath" ); |
上面的所有代码基本上算是模板代码了,用的时候多看手册,拷贝粘贴就ok了
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述