# xmlreader **Repository Path**: luzhizero/xmlreader ## Basic Information - **Project Name**: xmlreader - **Description**: xml文件解析整理 - **Primary Language**: Java - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2020-01-08 - **Last Updated**: 2020-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README XML文档解析方式有四种,两大类 1.SAX解析(SAX) 特点: 1.一边扫描文档一边进行解析. 2.SAX解析方式相比于DOM速度更快 3.无需将整个文档加载到内存,因而内存消耗少 4.SAX可以在解析文档的任意时刻停止解析. 缺点: 1.缺乏内置IDE文件导航支持 2.不能够随机访问XML文档 3.不能再原地对xml进行修改 使用建议:数据量大的情况. 2.DOM解析(DOM,JDOM,DOM4J) 特点: 1.将xml文件全部读取到内存中形成DOM树.然后进行解析 2.可以进行随机访问 3.可以在原地对xml文件进行修改 4.api容易学习 缺点: 1.大文件情况下会造成内存溢出无法使用的情况. 2.因为会先读取全部文件,所以解析效率上不如sax 建议使用:数据经常修改,数据量较小的时候 sax文件的解析方式 得到xml文件对应的资源,可以是xml的输入流,文件或uri 得到SAX解析工厂(SAXParserFactory) 由解析工厂生产一个SAX解析器(SAXParser) 传入输入流和handler给解析器,调用parse()方法解析 xml文件内容如下 ``` 张三 18 李四 18 ``` 1.首先创建一个SAXReaderHandler并继承DefaultHandler ``` package com.lzleang.saxreader; import com.lzleang.model.Student; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; import java.util.ArrayList; import java.util.List; public class SAXReaderHandler extends DefaultHandler { //创建一个student集合用于存储数据 private List students ; private Student student; private String tag; //用来存储当前解析的标签名字 //每开始解析一次xml文件就会调用一次 @Override public void startDocument() throws SAXException { super.startDocument(); students = new ArrayList(); System.out.println("开始已SAX的方式解析文档"); } //每次结束解析是会进行调用 @Override public void endDocument() throws SAXException { super.endDocument(); System.out.println("sax的文档解析已结束"); } /** * * @param uri:命名空间 * @param localName :不带前缀的标签名 -->获取的是person * @param qName:带前缀的标签名 -->获取的是a:person * @param attributes:当前标签属性 * @throws SAXException */ //每一个标签开始时调用 @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { super.startElement(uri, localName, qName, attributes); System.out.println("标签<"+qName + ">解析开始"); //是否解析到了student标签 if("student".equals(qName)){ student = new Student(); for(int i = 0 ; i < attributes.getLength();i++){ if(attributes.getLocalName(i).equals("id")){ student.setId(Integer.parseInt(attributes.getValue(i))); } } } tag = qName; } //每一个标签结束时调用 @Override public void endElement(String uri, String localName, String qName) throws SAXException { super.endElement(uri, localName, qName); System.out.println("标签解析结束"); if("student".equals(qName)){ students.add(student); } tag=null; } //当解析到标签中的内容的时候调用(换行也是文本内容) @Override public void characters(char[] ch, int start, int length) throws SAXException { super.characters(ch, start, length); String contents = new String(ch, start, length).trim(); if (contents.length() > 0) { System.out.println("内容为-->" + contents); } else { System.out.println("内容为-->" + "空"); } if("name".equals(tag)){ student.setName(contents); } if("sex".equals(tag)){ student.setSex(contents); } if("age".equals(tag)){ student.setAge(Integer.parseInt(contents)); } } //将解析完成的模型集合返回 public List getStudents(){ return students; } } ``` 2.创建Student学生类 ``` package com.lzleang.model; public class Student { private Integer id; private String name; private String sex; private Integer age; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } @Override public String toString() { return "Student{" + "id=" + id + ", name='" + name + '\'' + ", sex='" + sex + '\'' + ", age=" + age + '}'; } } ``` 3.对SAX开始进行解析 ``` package com.lzleang.saxreader; import com.lzleang.model.Student; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import java.io.File; import java.util.List; public class SAXReader { public static void testSaxParser()throws Exception{ //创建sax解释器的工厂对象 SAXParserFactory parserFactory = SAXParserFactory.newInstance(); //使用sax解释器的工厂对象生产一个sax解释器 SAXParser saxParser = parserFactory.newSAXParser(); //创建需要解析的xml的file类 File file = new File("src/student.xml"); //创建解析器处理器对象 SAXReaderHandler saxReaderHandler = new SAXReaderHandler(); //使用sax解释器解释xml文件了。 saxParser.parse(file,saxReaderHandler); //获取结果 List students = saxReaderHandler.getStudents(); System.err.println(students); } public static void main(String[] args) throws Exception { testSaxParser(); } } ``` dom的文件解析方式 ``` package com.lzleang.domreader; import com.lzleang.model.Student; import org.w3c.dom.Document; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import java.io.IOException; import java.util.ArrayList; public class DOMReader { public static void testDomParser() throws ParserConfigurationException, IOException, SAXException { //创建一个DOM解析器工厂对象; DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); //通过工厂对象创建DOM解析器 DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); //解析文档 Document doc = documentBuilder.parse("src/student.xml");//doc 即为树状结构的存储对象,在内存中; ArrayList students = new ArrayList<>(); //获取节点 NodeList XMLpersonlist = doc.getElementsByTagName("student"); //获取遍历节点 for (int i = 0; i org.jdom jdom 2.0.2 ``` 解析相关 ``` package com.lzleang.jdomreader; import com.lzleang.model.Student; import org.jdom2.Attribute; import org.jdom2.Document; import org.jdom2.Element; import org.jdom2.JDOMException; import org.jdom2.input.SAXBuilder; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; public class JOMReader { public static void testJdomParser() throws JDOMException, IOException { File file = new File("src/student.xml"); SAXBuilder builder = new SAXBuilder(); Document document = builder.build(file); Element root = document.getRootElement(); List elements = root.getChildren(); List students = new ArrayList(); for(Element element:elements){ Student student = new Student(); //获取属性值 List attributes = element.getAttributes(); for(int i = 0 ; i < attributes.size();i++){ String name = attributes.get(i).getName(); if("id".equals(name)){ student.setId(attributes.get(i).getIntValue()); } } //获取子节点 List childrens = element.getChildren(); for(Element children:childrens){ if("name".equals(children.getName())){ student.setName(children.getText()); } if("sex".equals(children.getName())){ student.setSex(children.getText()); } if("age".equals(children.getName())){ student.setAge(Integer.parseInt(children.getText())); } } students.add(student); } System.out.println(students); } public static void main(String[] args) throws JDOMException, IOException { testJdomParser(); } } ``` 属性相关 ``` //属性相关操作 public static void attributeHandler() throws JDOMException, IOException { File file = new File("src/student.xml"); SAXBuilder builder = new SAXBuilder(); Document document = builder.build(file); Element rootElement = document.getRootElement(); List student = rootElement.getChildren("student"); Element element = student.get(0); //修改当前的id element.setAttribute("id","99"); //创建一个新属性并赋值 element.setAttribute("class","三年二班"); //删除属性 student.get(1).removeAttribute("id"); //将doc写入文件 saveXML(document); } ``` 标签相关 ``` //标签相关操作 public static void updateDomHandler() throws JDOMException, IOException { File file = new File("src/student.xml"); SAXBuilder builder = new SAXBuilder(); Document document = builder.build(file); Element rootElement = document.getRootElement(); //创建一个父标签 Element student = new Element("student"); student.setAttribute("id","3"); //创建子节点 Element name = new Element("name"); name.setText("周七"); Element sex = new Element("sex"); sex.setText("女"); Element age = new Element("age"); age.setText("28"); //节点挂载 student.addContent(name); student.addContent(sex); student.addContent(age); rootElement.addContent(student); //获取标签并修改内容 Element element = rootElement.getChildren().get(0).getChild("name"); element.setText("王五"); //删除标签 Element element1 = rootElement.getChildren().get(1); element1.getParent().removeContent(element1); //将doc写入文件 saveXML(document); } ``` Dom4j也可以很方便完成XML文档的创建、元素的修改、文档的查询遍历等,但dom4j稍比jdom复杂一点,不过在大片文档的情况下dom4j的性能要比jdom好。所以dom4j也是最常用以及最推荐使用的dom解析方式 pom ``` dom4j dom4j 1.6.1 ``` dom4j还支持迭代器进行遍历查询和修改,这里就不做演示了,只选用了我个人比较习惯的操作方式. ``` package com.lzleang.jdomreader; import com.lzleang.model.Student; import org.jdom2.Attribute; import org.jdom2.Document; import org.jdom2.Element; import org.jdom2.JDOMException; import org.jdom2.input.SAXBuilder; import org.jdom2.output.Format; import org.jdom2.output.XMLOutputter; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.util.ArrayList; import java.util.List; public class JOMReader { //xml解析相关 public static void testJdomParser() throws JDOMException, IOException { File file = new File("src/student.xml"); SAXBuilder builder = new SAXBuilder(); Document document = builder.build(file); Element root = document.getRootElement(); List elements = root.getChildren(); List students = new ArrayList(); for(Element element:elements){ Student student = new Student(); //获取属性值 List attributes = element.getAttributes(); for(int i = 0 ; i < attributes.size();i++){ String name = attributes.get(i).getName(); if("id".equals(name)){ student.setId(attributes.get(i).getIntValue()); } } //获取子节点 List childrens = element.getChildren(); for(Element children:childrens){ if("name".equals(children.getName())){ student.setName(children.getText()); } if("sex".equals(children.getName())){ student.setSex(children.getText()); } if("age".equals(children.getName())){ student.setAge(Integer.parseInt(children.getText())); } } students.add(student); } System.out.println(students); } //属性相关操作 public static void attributeHandler() throws JDOMException, IOException { File file = new File("src/student.xml"); SAXBuilder builder = new SAXBuilder(); Document document = builder.build(file); Element rootElement = document.getRootElement(); List student = rootElement.getChildren("student"); Element element = student.get(0); //修改当前的id element.setAttribute("id","99"); //创建一个新属性并赋值 element.setAttribute("class","三年二班"); //删除属性 student.get(1).removeAttribute("id"); //将doc写入文件 saveXML(document); } //标签相关操作 public static void updateDomHandler() throws JDOMException, IOException { File file = new File("src/student.xml"); SAXBuilder builder = new SAXBuilder(); Document document = builder.build(file); Element rootElement = document.getRootElement(); //创建一个父标签 Element student = new Element("student"); student.setAttribute("id","3"); //创建子节点 Element name = new Element("name"); name.setText("周七"); Element sex = new Element("sex"); sex.setText("女"); Element age = new Element("age"); age.setText("28"); //节点挂载 student.addContent(name); student.addContent(sex); student.addContent(age); rootElement.addContent(student); //获取标签并修改内容 Element element = rootElement.getChildren().get(0).getChild("name"); element.setText("王五"); //删除标签 Element element1 = rootElement.getChildren().get(1); element1.getParent().removeContent(element1); //将doc写入文件 saveXML(document); } //将doc写入文件 public static void saveXML(Document doc) { // 将doc对象输出到文件 try { // 创建xml文件输出流 XMLOutputter xmlopt = new XMLOutputter(); // 创建文件输出流 FileWriter writer = new FileWriter("src/student.xml"); // 指定文档格式 Format fm = Format.getPrettyFormat(); fm.setEncoding("UTF-8"); xmlopt.setFormat(fm); // 将doc写入到指定的文件中 xmlopt.output(doc, writer); writer.close(); } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) throws JDOMException, IOException { updateDomHandler(); } } ```