首页 > 百科知识 正文

xml文件的解析(xml文件查找)

时间:2023-11-20 23:30:45 阅读:668 作者:爱翔的橙子

1. 解析方式

1. 有两种解析方式,分别是:

  • DOM:即Document Object Model,文档对象模型,W3C推出的专门用于解析xml一种处理方式
  • SAX:Simple API for XML,一个开源社区推出的xml解析方式。

区别是:

  • DOM方式会将整个xml文件解析成为一个树状结构,并加载到内存中,这种方式有一个缺点,如果xml文档过大,则解析会非常缓慢,甚至会产生内存溢出,优点就是因为在内存中生成了一个树状结构,所以可以对任意节点元素进行增删改操作。
  • SAX方式则是一边读一边解析,读到那个节点元素就解析那个,基于事件驱动,优点就是查询速度快而且不会发生内存溢出,缺点就是无法进行增删改操作。

2. xml解析开发包:这三个解析包均支持DOM和SAX两种方式解析xml文件

  • JAXP:由sun公司推出的解析包,是JavaSE中的一部分,有以下几个包及其子包构成
  • org.w3c.dom:提供了以DOM方式解析xml文件的标准接口
  • org.xml.sax:提供了以SAX方式解析XML文件的标准接口
  • javax.xml:提供了解析XML文件的类,在javax.xml.parsers包中有几个工厂类,通过工厂类就可以获得以DOM方式或SAX方式解析XML文件解析器对象,分别是javax.xml.parsers.DocumentBuilderFactory 工厂类和 javax.xml.parsers.SAXParserFactory工厂类
  • Dom4J:由一个开源组织开发的解析实现包,常用这个包进行XML文件解析。
  • JDom:也是一个开源组织开发的解析包

2. 通过JDK中的解析器以DOM方式进行XML文件解析的实现代码

1. 基础实现

import java.io.IOException; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.w3c.dom.Document; import org.w3c.dom.node; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; /** * @ClassName:Demo1 * @Description:使用jdk中提供的包以DOM方式解析xml文件,代码步骤如下 */ public class Demo1 { public static void main(String[] args) { try { //1. 获取解析器的工程类对象DocumentBuilderFactory DocumentBuilderFactory domfac=DocumentBuilderFactory.newInstance(); //2. 通过工厂类获取DOM解析器对象 DocumentBuilder docb=domfac.newDocumentBuilder(); //3. 解析指定路径的xml文件,并返回一个Document对象,Document对象中保存着整个xml文件中所有的元素节点 Document doc=docb.parse("url"); //4. 依据节点元素的名称来获取节点元素,返回的是一个NodeList对象 NodeList list= doc.getElementsByTagName("name"); //5. 从NodeList对象中遍历获取节点元素Node对象 for(int i=0;i<list.getLength();i ){ Node node= list.item(i); //6. 通过Node对象来获取节点内的具体信息,或者进行增删改当前节点及子节点操作 System.out.println(node.getTextContent());;//获取当前节点中的文本数据 } } catch (ParserConfigurationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SAXException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }

2. 添加子节点和删除子节点

import java.io.IOException; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; public class Demo2 { public static void main(String[] args) { try { //1. 获取解析器的工程类对象DocumentBuilderFactory DocumentBuilderFactory domfac=DocumentBuilderFactory.newInstance(); //2. 通过工厂类获取DOM解析器对象 DocumentBuilder docb=domfac.newDocumentBuilder(); //3. 解析指定路径的xml文件,并返回一个Document对象,Document对象中保存着整个xml文件中所有的元素节点 Document doc=docb.parse("url"); //4. 创建节点元素对象,并添加文本内容 Element e=doc.createElement("节点元素名称"); e.setTextContent("文本内容"); //5. 依据节点元素的名称来获取节点元素,返回的是一个NodeList对象 NodeList list= doc.getElementsByTagName("name"); //6. 从NodeList对象中遍历获取节点元素Node对象 for(int i=0;i<list.getLength();i ){ Node node= list.item(i); //7. 通过Node对象来获取节点内的具体信息,或者进行增删改当前节点及子节点操作 System.out.println(node.getTextContent());;//获取当前节点中的文本数据 //8. 添加子节点 node.appendChild(e); //删除当前节点 /* Node parent=node.getParentNode(); parent.removeChild(node); */ } } catch (ParserConfigurationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SAXException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }

3. Document对象中数据的回写:当对xml文件解析成Document对象后,对Document对象进行修改后,需要回写到xml文件

import java.io.IOException; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; /** * @ClassName:Demo3 * @Description:通过javax.xml.transform.Transformer类将内存中的树形结构的DOM数据回写到文件中进行保存 */ public class Demo3 { public static void main(String[] args) { try { DocumentBuilderFactory domfac=DocumentBuilderFactory.newInstance(); DocumentBuilder docb=domfac.newDocumentBuilder(); Document doc=docb.parse("url"); NodeList list= doc.getElementsByTagName("name"); //进行增删改修改元素节点,然后回写,比如修改某个节点的文本内容 list.item(0).setTextContent("新文本内容"); /* * 数据回写代码 */ //首先获取javax.xml.transform.Transformer类 TransformerFactory transformerFactory=TransformerFactory.newInstance(); Transformer trans=transformerFactory.newTransformer(); //绑定要回写的Document对象 DOMSource doms=new DOMSource(doc); //指定要回写到哪个xml文件中,参数写系统绝对路径或相对于当前类文件的相对路径 //或者是一个File类型的对象,也可以是一个输出流对象 StreamResult sr=new StreamResult("url"); //进行回写 trans.transform(doms, sr); } catch (ParserConfigurationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SAXException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (TransformerConfigurationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (TransformerException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }

4. 对解析xml文件生成Document对象以及将Document对象进行回写封装可以成为一个工具类:

import java.io.IOException; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import org.w3c.dom.Document; import org.xml.sax.SAXException; /** * @ClassName:MyDomUtil * @Description:解析xml文件以及部分处理操作的封装类 */ public class MyDomUtil { //获取解析指定xml文件得到的Document对象 public static Document readDocument(String url) throws ParserConfigurationException, SAXException, IOException{ DocumentBuilderFactory domfac=DocumentBuilderFactory.newInstance(); DocumentBuilder docb=domfac.newDocumentBuilder(); Document doc=docb.parse(url); return doc; } //向磁盘中的文件回写Document对象中的数据,url指定文件所在的路径,doc指定要回写的Document对象 public static void writeDocument(String url,Document doc) throws TransformerException{ TransformerFactory fac=TransformerFactory.newInstance(); Transformer trans=fac.newTransformer(); DOMSource dom=new DOMSource(doc); StreamResult sr=new StreamResult(url); trans.transform(dom, sr); } }

3. 通过JDK中的解析器以SAX方式进行XML文件解析的实现代码

1. SAX原理:SAX采用事件处理的方式解析XML文件,主要是两个部分进行解析,分别是解析器和事件处理器。

  • 在创建解析器时,需要绑定一个事件处理器,该事件处理器类中的方法是对每一个标签进行处理的逻辑
  • 解析器每读到XML文件中某个标签的某一部分,都会调用事件处理器类中的某一个对应解析该部分的方法进行处理,将标签该部分的数据作为参数传入方法中,然后通过方法中的逻辑进行处理。
  • 事件处理器由可以使用默认的org.xml.sax.helpers.DefaultHandler类,但如果要实现自己的处理逻辑,就必须继承该类,然后重写其中的部分方法来实现自己的逻辑,获取标签数据并对数据进行处理。

注意,SAX方式解析xml文件不能对标签元素进行增删改操作,只能查询。

xml文件的解析(xml文件查找)-第1张

2. 代码实现:

import java.io.IOException; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; /** * @ClassName:Demo4 * @Description:以SAX方式解析xml文件 */ public class Demo4 { public static void main(String[] args) { try { //获取解析器 SAXParserFactory fac=SAXParserFactory.newInstance();//解析器工厂 SAXParser saxp=fac.newSAXParser();//解析器 //解析XML文件,对于事件处理器需要由自己设计实现 saxp.parse("url", new MyHandler()); } catch (ParserConfigurationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SAXException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } /** * @ClassName:MyHandler * @Description:重写事件处理器中部分方法逻辑,实现自己事件处理器类 */ class MyHandler extends DefaultHandler{ /** * @Title:startElement * @Description:解析器解析xml文件中每一个标签的开始标签时(即<xx>),默认调用该方法,并把解析的内容传入方法参数 * @param uri * @param localName * @param qName 标签名 * @param attributes 标签中的所有属性 * @throws SAXException * @see org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes) */ public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { // 在此处实现自己的处理逻辑 System.out.println(qName); } /** * @Title:characters * @Description:解析器解析xml文件中的标签内的文本内容时),默认调用该方法将标签中的文本内容作为参数传入 * @param ch * @param start * @param length * @throws SAXException * @see org.xml.sax.helpers.DefaultHandler#characters(char[], int, int) */ @Override public void characters(char[] ch, int start, int length) throws SAXException { // 在此处实现自己的处理逻辑 System.out.println(new String(ch)); } /** * @Title:endElement * @Description:解析器解析xml文件中每一个标签的结束标签时(即</xx>),默认调用该方法,并把解析的内容传入方法参数 * @param uri * @param localName * @param qName 标签名 * @throws SAXException * @see org.xml.sax.helpers.DefaultHandler#endElement(java.lang.String, java.lang.String, java.lang.String) */ @Override public void endElement(String uri, String localName, String qName) throws SAXException { // 在此处实现自己的处理逻辑 System.out.println(qName); } }

4. 通过Dom4J包来实现对XML文件的解析

首先,必须导入dom4j的包才能使用

1.解析:

import java.util.List; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Element; import org.dom4j.io.SAXReader; public class Demo1 { public static void main(String[] args) { try { //获取解析器对象SAXReader,SAXReader是Dom4J包中SAX方式解析XML文件的类 SAXReader sax=new SAXReader(); //解析指定路径下的xml文件,获取该xml文件的Document对象 Document doc=sax.read("url"); //获取根节点,必须先获取根节点之后才能进行后续子标签的解析处理 //Dom4J中解析xml文件,获取标签节点时,必须一层一层的获取,也就是说,必须先获取父节点,然后才是子节点 Element root=doc.getRootElement(); //获取子节点,并进行解析 List<Element> list1=root.elements();//获取root节点下所有的直接子节点,并以集合形式返回 List<Element> list2=root.elements("name");//获取root节点下所有的直接子节点中指定名称的节点,并以集合形式返回 Element e=root.element("name");//获取root节点下所有的直接子节点中指定名称的第一个节点 String text=e.getText();//获取标签节点内容 } catch (DocumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }

2. 实现节点元素的增删改:

import java.io.FileOutputStream; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Element; import org.dom4j.io.OutputFormat; import org.dom4j.io.SAXReader; import org.dom4j.io.XMLWriter; public class Demo2 { public static void main(String[] args) throws Exception { //获取解析器对象 SAXReader reader=new SAXReader(); //解析获取XML文件的Document对象 Document doc=reader.read("url"); //获取根节点 Element root=doc.getRootElement(); //获取要修改的节点,在这个节点下添加一个子节点 Element e=root.element("name"); Element child=e.addElement("childname");//在这个节点下添加一个名为childname的子节点并返回这个子节点 //设置文本内容 child.setText("xxx"); //回写,使用专用的一个流XMLWriter OutputFormat format=OutputFormat.createPrettyPrint();//如果使用该类,则输出到文件中后,会有对齐空格符 format.setEncoding("utf-8");//设置文件编码 XMLWriter writer=new XMLWriter(new FileOutputStream("目标文件路径"),format); writer.write(doc); writer.close();//关闭流 } }

xml文件的解析(xml文件查找)-第2张

,

版权声明:该问答观点仅代表作者本人。如有侵犯您版权权利请告知 cpumjj@hotmail.com,我们将尽快删除相关内容。