java解析xml
2015-12-12 11:29
543 查看
最近学习了xml的解析,感觉应该总结一下:
xml在开发中还是非常重要的,主要用来当做配置文件,存储和传输数据用的。所以如何来解析xml就尤为重要。
xml的解析方式有两种:dom和sax。两种方式各有优缺点:
缺点:如果文件过大,造成内存溢出
优点:方便实现增删改操作
- 从上到下,一行一行解析,解析到某个对象,返回对象名称
缺点:不能实现增删改操作
优点:文件过大时,不会造成内存溢出,方便实现查询操作。
java 解析xml:java解析xml的方式称为jaxp。jaxp是javase的一部分。jaxp解析器在jdk的javax.xml.parsers包里面。这里面当然也包含了两种解析方式。
要得到dom解析器还真有点麻烦:先要创建dom解析器工厂,然后根据工厂得到dom解析器,再使用parse方法与xml连接。这样,该对象就代表了所指定的xml文件。
最后得到的document就代表整个xml文件了。
回写xml:
使用dom可以对xml文件进行增删改查,当然这是在内存中进行操作的,那么如何将修改过的document写回原文件中呢?这时,就需要用到回写xml所需要的类了。
这其中传的参数document就是你得到解析器时的Document对象,PATH为写回的路径。
因为上面两个操作比较固定,所以我把它们封装成了一个工具类:
使用dom解析xml当然少不了对其内容的增删改查:
sax是边读边解析,所以:
**当解析到开始标签时候,自动执行startElement方法,该方法中的qName参数就为元素开始标签
**当解析到文本时,自动执行characters方法,该方法的三个参数可转换为String类的构造方法,用此来new String对象
**当解析到结束标签是,自动执行endElement方法,该方法中的qName参数就为元素结束标签
sax只能完成查询操作:
xml在开发中还是非常重要的,主要用来当做配置文件,存储和传输数据用的。所以如何来解析xml就尤为重要。
xml的解析方式有两种:dom和sax。两种方式各有优缺点:
*dom方式解析
根据xml的层级结构在内存中分配一个树形结构,把xml的标签、属性、文本都封装成对象。缺点:如果文件过大,造成内存溢出
优点:方便实现增删改操作
**sax方式解析
采用事件驱动的方式,边读边解析- 从上到下,一行一行解析,解析到某个对象,返回对象名称
缺点:不能实现增删改操作
优点:文件过大时,不会造成内存溢出,方便实现查询操作。
java 解析xml:java解析xml的方式称为jaxp。jaxp是javase的一部分。jaxp解析器在jdk的javax.xml.parsers包里面。这里面当然也包含了两种解析方式。
dom解析方式:
先说说jaxp创建dom解析器:要得到dom解析器还真有点麻烦:先要创建dom解析器工厂,然后根据工厂得到dom解析器,再使用parse方法与xml连接。这样,该对象就代表了所指定的xml文件。
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder documentBuilder=documentBuilderFactory.newDocumentBuilder(); Document document = documentBuilder.parse(PATH);
最后得到的document就代表整个xml文件了。
回写xml:
使用dom可以对xml文件进行增删改查,当然这是在内存中进行操作的,那么如何将修改过的document写回原文件中呢?这时,就需要用到回写xml所需要的类了。
TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer =transformerFactory.newTransformer(); transformer.transform(new DOMSource(document), new StreamResult(PATH));
这其中传的参数document就是你得到解析器时的Document对象,PATH为写回的路径。
因为上面两个操作比较固定,所以我把它们封装成了一个工具类:
public class DomUtils { /* * 在使用该类时,请先初始化PATH,即先调用setPATH()方法。 * */ private static String PATH = ""; public static void setPATH(String path){ PATH = path; } public static String getPATH(){ return PATH; } //获取xml的document对象 public static Document getDocument(){ try { DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder documentBuilder=documentBuilderFactory.newDocumentBuilder(); Document document = documentBuilder.parse(PATH); return document; } catch (ParserConfigurationException e) { e.printStackTrace(); } catch (SAXException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } //根据document回写xml public static void xmlWriters(Document document){ try{ TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer =transformerFactory.newTransformer(); transformer.transform(new DOMSource(document), new StreamResult(PATH)); }catch (TransformerConfigurationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (TransformerException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
使用dom解析xml当然少不了对其内容的增删改查:
//使用jaxp添加节点,在school标签下面再添加一个class标签 public static void addNode() throws Exception{ /* * 1、创建解析器工厂 * 2、创建解析器 * 3、解析xml,得到document * 4、得到school标签 * 5、创建class标签 * 6、创建文本 * 7、把文本添加到class下 * 8、把class添加到school下 * 9、回写xml * */ DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); Document document= documentBuilder.parse("src\\01.xml"); //4、得到school标签 Node school= document.getElementsByTagName("school").item(0); //5、创建class标签 Element class1 =document.createElement("class"); //6、创建文本 Text text1=document.createTextNode("shen12"); // 7、把文本添加到class下 class1.appendChild(text1); //8、吧class添加到school下 school.appendChild(class1); //回写xml /* * 1.创建transformerfactory的对象 * 2、根据transformerfactory的对象创建transformer对象 * 3、使用transformer的transform方法 transform(Source xmlSource, Result outputTarget) * 传递两个参数 * 1,DOMSource对象,以 Document Object Model(DOM)树的形式充当转换 Source 树的持有者。 * 2.streamResult对象,充当转换结果的持有者,可以为 XML、纯文本、HTML 或某些其他格式的标记。 * */ TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer=transformerFactory.newTransformer(); transformer.transform(new DOMSource(document), new StreamResult("src\\01.xml")); } }
//删除节点 public static void delNode() throws Exception{ /* * 删除第三个name标签 *1、创建解析器工厂 *2、创建解析器 *3、解析,得到doucment *4、得到第三个标签 *5、得到这个标签的父标签 *6、通过父标签删除 *7、回写xml * * */ DocumentBuilderFactory documentBuilderFactory= DocumentBuilderFactory.newInstance(); DocumentBuilder documentBuilder=documentBuilderFactory.newDocumentBuilder(); Document document=documentBuilder.parse("src\\01.xml"); NodeList nameList =document.getElementsByTagName("name"); Node nameBy3 =nameList.item(2); Node namenParent =nameBy3.getParentNode(); namenParent.removeChild(nameBy3); TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer=transformerFactory.newTransformer(); transformer.transform(new DOMSource(document),new StreamResult("src\\01.xml"));
<pre name="code" class="java"> //使用jaxp修改节点 public static void setNode() throws Exception{ /* *修改第二个name的名称为杨泽斌 *1、创建解析器工厂 *2、创建解析器 *3、解析,得到doucment *4、得到name的list *5、得到第二的name *6、修改文本为杨泽斌 *7、回写xml * */ DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder docmBuilder=documentBuilderFactory.newDocumentBuilder(); Document document=docmBuilder.parse("src\\01.xml"); NodeList nameList =document.getElementsByTagName("name"); Node nameBy2=nameList.item(1); nameBy2.setTextContent("杨泽斌"); TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer=transformerFactory.newTransformer(); transformer.transform(new DOMSource(document), new StreamResult("src\\01.xml")); }
<pre name="code" class="java"> //遍历xml的所有元素名称,并打印 public static void listNodeName() throws Exception{ /* *1、创建解析器工厂 *2、创建解析器 *3、解析,得到doucment * *4、得到根节点 *5、得到根节点的子节点 *6.。。。。 * */ DocumentBuilderFactory documentBuilderFactory= DocumentBuilderFactory.newInstance(); DocumentBuilder documentBuilder=documentBuilderFactory.newDocumentBuilder(); Document document=documentBuilder.parse("src\\01.xml"); //编写一个方法来实现递归操作 list1(document); } private static void list1(Node node) { //判断nodetype是否为元素,打印(因为xml会解析换行和空格,而这些并不是我们想要的) if(node.getNodeType()==Node.ELEMENT_NODE){ System.out.println(node.getNodeName()); } //得到下一层的名称的list NodeList list =node.getChildNodes(); //得到每一个node for(int i = 0; i<list.getLength();i++){ Node node1 = list.item(i); //继续遍历下一层的元素 list1(node1); } }
再说说sax解析:
由于sax是基于事件驱动的,遇到事件会自动执行对应方法,所以我们要做的就是改变这些方法的内容,从而使执行后产生不同的效果。sax是边读边解析,所以:
**当解析到开始标签时候,自动执行startElement方法,该方法中的qName参数就为元素开始标签
**当解析到文本时,自动执行characters方法,该方法的三个参数可转换为String类的构造方法,用此来new String对象
**当解析到结束标签是,自动执行endElement方法,该方法中的qName参数就为元素结束标签
sax只能完成查询操作:
public class saxTest { public static void main(String[] args) throws Exception{ /* * 1、创建解析器工厂 * 2、创建解析器 * 3、执行parse方法 * 4、自己创建一个类,继承DefaultHandler * 5、自己重写其中的三个方法:startElement方法,characters方法,endElement方法 * */ SAXParserFactory saxParserFactory = SAXParserFactory.newInstance(); SAXParser saxParser =saxParserFactory.newSAXParser(); saxParser.parse("src\\02.xml", new MyDefault2()); } } class MyDefault2 extends DefaultHandler{ //获取name标签的值 boolean flag = false; @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { //判断qName是否为name标签 if("name".equals(qName)){ flag=true; } } @Override public void characters(char[] ch, int start, int length) throws SAXException { //是Name标签则打印 if(flag){ System.out.println(new String(ch,start,length)); } } @Override public void endElement(String uri, String localName, String qName) throws SAXException { //重置 flag=false; } } class MyDefault1 extends DefaultHandler{ //以整个文档的形式打印 @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { System.out.print("<"+qName+">"); } @Override public void characters(char[] ch, int start, int length) throws SAXException { System.out.print(new String(ch,start,length)); } @Override public void endElement(String uri, String localName, String qName) throws SAXException { System.out.print("</"+qName+">"); } }
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- 插入排序
- 冒泡排序
- 堆排序
- 快速排序
- 二叉查找树