zoukankan      html  css  js  c++  java
  • java解析xml几种方式

    1. dom解析

    DOM是用与平台和语言无关的方式表示XML文档的官方W3C标准。DOM是以层次结构组织的节点或信息片断的集合。这个层次结构允许开发人员在树中寻找特定信息。分析该

    结构通常需要加载整个文档和构造层次结构,然后才能做任何工作。由于它是基于信息层次的,因而DOM被认为是基于树或基于对象的。

    dom解析优点:

    首先,由于树在内存中是持久的,因此可以修改它以便应用程序能对数据和结构作出更改。它还可以在任何时候在树中上下导航,而不是像SAX那样是一次性的处理。DOM使用起来也要简单得多。

    实例:

    节点信息类

    public class Employee {
    
    	private String name;
    	
    	private String sex;
    	
    	private int age;
    
    	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 int getAge() {
    		return age;
    	}
    
    	public void setAge(int age) {
    		this.age = age;
    	}
    
    	@Override
    	public int hashCode() {
    		final int prime = 31;
    		int result = 1;
    		result = prime * result + age;
    		result = prime * result + ((name == null) ? 0 : name.hashCode());
    		result = prime * result + ((sex == null) ? 0 : sex.hashCode());
    		return result;
    	}
    
    	@Override
    	public boolean equals(Object obj) {
    		if (this == obj)
    			return true;
    		if (obj == null)
    			return false;
    		if (getClass() != obj.getClass())
    			return false;
    		Employee other = (Employee) obj;
    		if (age != other.age)
    			return false;
    		if (name == null) {
    			if (other.name != null)
    				return false;
    		} else if (!name.equals(other.name))
    			return false;
    		if (sex == null) {
    			if (other.sex != null)
    				return false;
    		} else if (!sex.equals(other.sex))
    			return false;
    		return true;
    	}
    
    	@Override
    	public String toString() {
    		return "Employee [name=" + name + ", sex=" + sex + ", age=" + age + "]";
    	}
    
    	public Employee(String name, String sex, int age) {
    		super();
    		this.name = name;
    		this.sex = sex;
    		this.age = age;
    	}
    
    	public Employee() {
    		super();
    	}
    }
    dom解析类:

    public class DomXmlParse {
    
    	public Document document;
    
    	public DomXmlParse() {
    		init();
    	}
    
    	public void init() {
    		try {
    			DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory
    					.newInstance();
    			DocumentBuilder documentBuilder;
    			documentBuilder = documentBuilderFactory.newDocumentBuilder();
    			this.document = documentBuilder.newDocument();
    		} catch (ParserConfigurationException e) {
    			e.printStackTrace();
    			System.out.println(e.getMessage());
    		}
    	}
    
    	public void createXml(List<Employee> list, String rootName, String fileName) {
    		Element root = this.document.createElement(rootName);
    		this.document.appendChild(root);
    		if (null != list && list.size() > 0) {
    			for (Employee detail : list) {
    				Element employee = createEmploy(detail);
    				root.appendChild(employee);
    			}
    		}
    		TransformerFactory tf = TransformerFactory.newInstance();
    		try {
    			Transformer transformer = tf.newTransformer();
    			DOMSource domSource = new DOMSource(this.document);
    			transformer.setOutputProperty(OutputKeys.ENCODING, "gb2312");
    			transformer.setOutputProperty(OutputKeys.INDENT, "yes");
    			PrintWriter pw = new PrintWriter(new FileOutputStream(fileName));
    			StreamResult streamResult = new StreamResult(pw);
    			transformer.transform(domSource, streamResult);
    			System.out.println("创建xml文件成功");
    		} catch (TransformerConfigurationException e) {
    			e.printStackTrace();
    		} catch (IOException e) {
    			e.printStackTrace();
    		} catch (TransformerException e) {
    			e.printStackTrace();
    		}
    	}
    
    	public Element createEmploy(Employee employee){
    		Element employeElement = this.document.createElement("employee");
    		Element nameElement = this.document.createElement("name");
    		nameElement.appendChild(this.document.createTextNode(employee.getName()));
    		employeElement.appendChild(nameElement);
    		Element sexElement = this.document.createElement("sex");
    		sexElement.appendChild(this.document.createTextNode(employee.getSex()));
    		employeElement.appendChild(sexElement);
    		Element ageElement = this.document.createElement("age");
    		ageElement.appendChild(this.document.createTextNode(String.valueOf(employee.getAge())));
    		employeElement.appendChild(ageElement);
    		return employeElement;
    	}
    
    	public void parseXml(String fileName) {
    		try {
    			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    			DocumentBuilder db = dbf.newDocumentBuilder();
    			Document document = db.parse(fileName);
    			NodeList nodeList = document.getChildNodes();
    			for (int i = 0; i < nodeList.getLength(); i++) {
    				System.out.println("节点类型:"+nodeList.item(i).getNodeType());
    				System.out.println("节点名:"+nodeList.item(i).getNodeName()
    						+ ":" + "文本值"+nodeList.item(i).getTextContent());
    				Node nodeP = nodeList.item(i);
    				NodeList nodeInfo = nodeP.getChildNodes();
    				for (int j = 0; j < nodeInfo.getLength(); j++) {
    					System.out.println("节点类型:"+nodeInfo.item(j).getNodeType());
    					System.out.println("节点名:"+nodeInfo.item(j).getNodeName()
    							+ ":" + "文本值"+nodeInfo.item(j).getTextContent());
    					Node node = nodeInfo.item(j);
    					NodeList enodeMeta = node.getChildNodes();
    					for (int k = 0; k < enodeMeta.getLength(); k++) {
    						System.out.println("节点类型:"+enodeMeta.item(k).getNodeType());
    						System.out.println("节点名:"+enodeMeta.item(k).getNodeName()
    								+ ":" + "文本值"+enodeMeta.item(k).getTextContent());
    					}
    				}
    			}
    			System.out.println("解析完毕");
    		} catch (FileNotFoundException e) {
    			System.out.println(e.getMessage());
    		} catch (ParserConfigurationException e) {
    			System.out.println(e.getMessage());
    		} catch (SAXException e) {
    			System.out.println(e.getMessage());
    		} catch (IOException e) {
    			System.out.println(e.getMessage());
    		}
    	}
    }

     测试

    	List<Employee> listEmployees = new ArrayList<Employee>();
    	
    	@Before
    	public void init(){
    		Employee employee1 = new Employee("张三", "m", 20);
    		Employee employee2 = new Employee("李四", "d", 30);
    		Employee employee3 = new Employee("王武", "x", 40);
    		Employee employee4 = new Employee("大方", "g", 50);
    		listEmployees.add(employee1);
    		listEmployees.add(employee2);
    		listEmployees.add(employee3);
    		listEmployees.add(employee4);
    	}
    	
    	
    	
    	@Test
    	@SuppressWarnings({ "rawtypes", "unchecked" })
    	public void test1(){
    		DomXmlParse domXmlParse = new DomXmlParse();
    		String fileName = "D:"+File.separator+"test"+File.separator+"xml"+File.separator+"employeeDom.xml";
    		domXmlParse.createXml(listEmployees, "employees", fileName);
    		domXmlParse.parseXml(fileName);
    	}
    

    生成的xml文档结构

    <?xml version="1.0" encoding="GB2312" standalone="no"?>
    <employees>
    <employee>
    <name>张三</name>
    <sex>m</sex>
    <age>20</age>
    </employee>
    <employee>
    <name>李四</name>
    <sex>d</sex>
    <age>30</age>
    </employee>
    <employee>
    <name>王武</name>
    <sex>x</sex>
    <age>40</age>
    </employee>
    <employee>
    <name>大方</name>
    <sex>g</sex>
    <age>50</age>
    </employee>
    </employees>

    2. sax解析

    SAX解析器采用了基于事件的模型,它在解析XML文档的时候可以触发一系列的事件,当发现给定的tag的时候,它可以激活一个回调方法,告诉该方法制定的标签已经找到。

    SAX对内存的要求通常会比较低,因为它让开发人员自己来决定所要处理的tag.特别是当开发人员只需要处理文档中所包含的部分数据时,SAX这种扩展能力得到了更好的体

    现。但用SAX解析器的时候编码工作会比较困难,而且很难同时访问同一个文档中的多处不同数据。

    sax解析事件回调类:

    public class SaxHandler extends DefaultHandler {
    	
    	private HashMap<String, String> map = null;
    	private List<HashMap<String, String>> list = null;
    	/**
    	 * 正在解析的元素的标签
    	 */
    	private String currentTag = null;
    	/**
    	 * 正在解析的元素的值
    	 */
    	private String currentValue = null;
    	private String nodeName = null;
    	
    	public List<HashMap<String, String>> getList(){
    		return list;
    	}
    
    	public SaxHandler(String nodeName) {
    		this.nodeName = nodeName;
    	}
    
    	@Override
    	public void startDocument() throws SAXException {
    		// TODO 当读到一个开始标签的时候,会触发这个方法
    		list = new ArrayList<HashMap<String,String>>();
    	}
    
    	@Override
    	public void startElement(String uri, String localName, String name,
    			Attributes attributes) throws SAXException {
    		// TODO 当遇到文档的开头的时候,调用这个方法
    		if(name.equals(nodeName)){
    			map = new HashMap<String, String>();
    		}
    		if(attributes != null && map != null){
    			for(int i = 0; i < attributes.getLength();i++){
    				map.put(attributes.getQName(i), attributes.getValue(i));
    			}
    		}
    		currentTag = name;
    	}
    	
    	@Override
    	public void characters(char[] ch, int start, int length)
    			throws SAXException {
    		// TODO 这个方法用来处理在XML文件中读到的内容
    		if(currentTag != null && map != null){
    			currentValue = new String(ch, start, length);
    			if(currentValue != null && !currentValue.trim().equals("") && !currentValue.trim().equals("
    ")){
    				map.put(currentTag, currentValue);
    			}
    		}
    		currentTag=null;
    		currentValue=null;
    	}
    
    	@Override
    	public void endElement(String uri, String localName, String name)
    			throws SAXException {
    		// TODO 在遇到结束标签的时候,调用这个方法
    		if(name.equals(nodeName)){
    			list.add(map);
    			map = null;
    		}
    		super.endElement(uri, localName, name);
    	}
    }

    sax解析类:

    public abstract class SaxXmlParse{
    	
    	public static List<HashMap<String, String>> _readXml(InputStream input, String nodeName){
    		try {
    			SAXParserFactory spf = SAXParserFactory.newInstance();
    			SAXParser parser = spf.newSAXParser();
    			SaxHandler handler = new SaxHandler(nodeName);
    			parser.parse(input, handler);
    			input.close();
    			return handler.getList();
    		} catch (ParserConfigurationException e) {
    			e.printStackTrace();
    		} catch (SAXException e) {
    			e.printStackTrace();
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    		return null;
    	}
    }
    测试:
    <span style="white-space:pre">	</span>@Test
    	public void saxTest(){
    		String fileName = "D:"+File.separator+"test"+File.separator+"xml"+File.separator+"employeeDom.xml";
    		try {
    			FileInputStream input = new FileInputStream(fileName);
    			List<HashMap<String, String>> list = SaxXmlParse._readXml(input, "employees");
    			for(HashMap<String, String> p : list){
    				System.out.println(p.toString());
    			}
    		} catch (FileNotFoundException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    	}

    3. JDom解析

    JDOM的目的是成为Java特定文档模型,它简化与XML的交互并且比使用DOM实现更快。由于是第一个Java特定模型,JDOM一直得到大力推广和促进。正在考虑通过“Java规

    范请求JSR-102”将它最终用作“Java标准扩展”。从2000年初就已经开始了JDOM开发。

    JDOM与DOM主要有两方面不同。首先,JDOM仅使用具体类而不使用接口。这在某些方面简化了API,但是也限制了灵活性。第二,API大量使用了Collections类,简化了那些

    已经熟悉这些类的Java开发者的使用。

    JDOM文档声明其目的是“使用20%(或更少)的精力解决80%(或更多)Java/XML问题”(根据学习曲线假定为20%)。JDOM对于大多数Java/XML应用程序来说当然是有的,

    并且大多数开发者发现API比DOM容易理解得多。JDOM还包括对程序行为的相当广泛检查以防止用户做任何在XML中无意义的事。然而,它仍需要您充分理解XML以便做一些

    超出基本的工作(或者甚至理解某些情况下的错误)。这也许是比学习DOM或JDOM接口都更有意义的工作。

    JDom解析类:

    public class JDomXmlParse  {
    
    	@SuppressWarnings("unchecked")
    	public void parseXml(String fileName) {
    		try {
    			InputStream in = new FileInputStream(fileName);
    			SAXBuilder saxBuilder = new SAXBuilder();
    			Document document = saxBuilder.build(in);
    			Element root = document.getRootElement();
    			System.out.println(root.getName());
    			List<Element> nodes = root.getChildren();
    			for(Element element : nodes){
    				String name = element.getChildText("name");
    				String age = element.getChildText("age");
    				String sex = element.getChildText("sex");
    				System.out.println(name);
    				System.out.println(age);
    				System.out.println(sex);
    			}
    		} catch (FileNotFoundException e) {
    			e.printStackTrace();
    		} catch (JDOMException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		} catch (IOException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    	}
    }

    测试:

    @Test
    	public void jdomTest(){
    		String fileName = "D:"+File.separator+"test"+File.separator+"xml"+File.separator+"employeeDom.xml";
    		JDomXmlParse jDomXmlParse = new JDomXmlParse();
    		jDomXmlParse.parseXml(fileName);
    	}

    4. dom4j解析

    虽然DOM4J代表了完全独立的开发结果,但最初,它是JDOM的一种智能分支。它合并了许多超出基本XML文档表示的功能,包括集成的XPath支持、XML Schema支持以及用

    于大文档或流化文档的基于事件的处理。它还提供了构建文档表示的选项,它通过DOM4J API和标准DOM接口具有并行访问功能。从2000下半年开始,它就一直处于开发之

    中。

    为支持所有这些功能,DOM4J使用接口和抽象基本类方法。DOM4J大量使用了API中的Collections类,但是在许多情况下,它还提供一些替代方法以允许更好的性能或更直接
     
    的编码方法。直接好处是,虽然DOM4J付出了更复杂的API的代价,但是它提供了比JDOM大得多的灵活性。

    在添加灵活性、XPath集成和对大文档处理的目标时,DOM4J的目标与JDOM是一样的:针对Java开发者的易用性和直观操作。它还致力于成为比JDOM更完整的解决方案,实
     
    现在本质上处理所有Java/XML问题的目标。在完成该目标时,它比JDOM更少强调防止不正确的应用程序行为。

    DOM4J是一个非常非常优秀的Java XML API,具有性能优异、功能强大和极端易用使用的特点,同时它也是一个开放源代码的软件。如今你可以看到越来越多的Java软件都在 

    使用DOM4J来读写XML,特别值得一提的是连Sun的JAXM也在用DOM4J.

    dom解析类:

    public class Dom4jXmlParse {
    
    	@SuppressWarnings("rawtypes")
    	public void parseXml(String fileName) throws DocumentException {
    		SAXReader saxReader = new SAXReader();
    		Document document = saxReader.read(fileName);
    		Element root = document.getRootElement();
    		System.out.println(root.getName());
    		for(Iterator iterator = root.elementIterator() ; iterator.hasNext();){
    			Element element = (Element) iterator.next();
    			System.out.println(element.getName());
    			for(Iterator childIterator = element.elementIterator() ; childIterator.hasNext();){
    				Element childElement = (Element) childIterator.next();
    				System.out.println(childElement.getName()+":"+childElement.getText());
    			}
    		}
    	}
    	
    	/**
    	 * 用Visitor模式解析
    	 * @param fileName
    	 * @throws DocumentException
    	 */
    	public void visitorParseXml(String fileName) throws DocumentException{
    		SAXReader saxReader = new SAXReader();
    		Document document = saxReader.read(fileName);
    		Visitor visitor = new Visitor();
    		document.accept(visitor);
    	}
    	
    }

    dom4j支持用Visitor模式访问节点,属性,只要继承类VisitorSupport的Visitor,注意,这个Visitor是自动遍历所有子节点的。如果是root.accept(MyVisitor),将遍历

    子节点

    public class Visitor extends VisitorSupport{
    
    	@Override
    	public void visit(Element element) {
    		if(element.isTextOnly()){
    			System.out.println(element.getName()+"--"+element.getText());
    		}else{
    			System.out.println(element.getName());
    		}
    	}
    
    	@Override
    	public void visit(Attribute attribute) {
    		System.out.println(attribute.getName() + "--" +attribute.getText());
    	}
    }
    测试
    @Test
    	public void dom4jTest() throws DocumentException{
    		String fileName = "D:"+File.separator+"test"+File.separator+"xml"+File.separator+"employeeDom.xml";
    		Dom4jXmlParse dom4jXmlParse = new Dom4jXmlParse();
    		dom4jXmlParse.parseXml(fileName);
    	}
    	
    	@Test
    	/**
    	 * Visitor方式解析xml文件
    	 * @throws DocumentException
    	 */
    	public void dom4jVisitorTest() throws DocumentException{
    		String fileName = "D:"+File.separator+"test"+File.separator+"xml"+File.separator+"employeeDom.xml";
    		Dom4jXmlParse dom4jXmlParse = new Dom4jXmlParse();
    		dom4jXmlParse.visitorParseXml(fileName);
    	}

  • 相关阅读:
    Java1.0-1.11各个版本的新特性
    Java在ServletContextListener、过滤器、拦截器解决对象无法注入问题
    实验七 Web应用测试
    第四次作业
    实验5
    实验4
    实验3
    把一个英语句子中的单词次序颠倒后输出。例如输入“how are you”,输出“you are how”;
    1. java.lang.AbstractMethodError: org.mybatis.spring.transaction.SpringManagedTransaction.getTimeout()Ljava/lang/Integer;报错问题
    在eclipse中新建maven项目 js,css路径失效问题
  • 原文地址:https://www.cnblogs.com/marcotan/p/4256909.html
Copyright © 2011-2022 走看看