Java的四种解析XML方式

XML:EXtensible Markup Language 可扩展标记语言,主要用于数据的传输与共享,由于其传输与共享数据简单那的这一特性,广泛用于互联网等数据的传输,以及一些框架软件的配置文件.相对于HTML的语法相对松散的特性,XML的语法十分严谨。XML的验证主要通过DTD文件或者Schema文件。(具体baidu或google)

Java解析XML 提供了四种解析方式,每一种方式都有其特点。

首先是想xml.xml文件

<?xml version="1.0" encoding="gbk"?>
<books>
	<book>
		<bookName>《三国》</bookName>
		<author>罗贯中</author>
	</book>
		<book>
		<bookName>《西游记》</bookName>
		<author>吴承恩</author>
	</book>
		<book>
		<bookName>《水浒》</bookName>
		<author>施耐庵</author>
	</book>
</books>

第一种:使用DOM的方式解析XML。

DOM是用与平台和语言无关的方式表示XML的官方W3C标准。使用DOM方式能十分方便的解析小型XML文档。其原理是一次性加载整个XML文档到内存,在内存中组织成树形结构,并通过节点与节点的联系来解析XML文档,因而DOM也被认为是基于对象获树的。其特点是简单易学,整个树在内存中是持久的,因而可以它支持以便应用程序能对数据或结构进行修改。但正因为起一次性加载整个文档,其所占用的内存比较大,对内存要求比较高。

public static void main(String[] args) {
		System.out.println("Hello,world!");
		String fileName = "D://java/xml/xml.xml";
		File file = new File(fileName);
		XMLDemo xmlDemo = new XMLDemo();
		try {
			xmlDemo.parseXMLByDOM(file);
		} catch (Exception e) {
			// TODO: handle exceptio
			e.printStackTrace();
		}
	}
	
	//通过DOM的方式解析XML文件
	public void parseXMLByDOM(File file)throws Exception{
		
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		DocumentBuilder builder = factory.newDocumentBuilder();
		Document doc = builder.parse(file);
		NodeList nodeList = doc.getElementsByTagName("book");
		for (int i = 0; i < nodeList.getLength(); i++) {
			String book = doc.getElementsByTagName("bookName").item(i).getFirstChild().getNodeValue();
			String author = doc.getElementsByTagName("author").item(i).getFirstChild().getNodeValue();
			System.out.println(book+"的作者是:"+author);
		}
		
	}

具体当上面的xml文件的编码方式改成Utf-8时有时可能报com.sun.org.apache.xerces.internal.impl.io.MalformedByteSequenceException错误具体如下:


具体是因为xml文件申明的编码格式与xml文件保存时的编码格式不一致所造成的,因此,有可能encoding=gbk也是会出错的关键在与你电脑保存的编码格式。

第二种SAX解析XML方式

可以说SAX是基于事件的XML解析方式,SAX解析器在解析XML输入的构件时就报告事件,但不会和DOM那样存储文档,有时间来决定是否构件数据结构。在SAX解析时,需要一个处理器来定义不同的解析器事件的时间动作。ContentHandler定义了一下毁掉方法:

StartDocuemnt与endDocument  文档开始或结束时使用一次    startElement与endElement 遇到起始或结束标签时调用  characters遇到字符数据时使用.

SAX 解析DEMO如下:

public static void main(String[] args) {
		System.out.println("Hello,world!");
		String fileName = "D://java/xml/xml.xml";
		File file = new File(fileName);
		XMLDemo xmlDemo = new XMLDemo();
		try {
			// xmlDemo.parseXMLByDOM(file);
			xmlDemo.parseXMLBySAX(file);
		} catch (Exception e) {
			// TODO: handle exceptio
			e.printStackTrace();
		}
	}

	private void parseXMLBySAX(File file) throws Exception {
		SAXParserFactory spf = SAXParserFactory.newInstance();
		SAXParser saxParser = spf.newSAXParser();
		saxParser.parse(file, new PraseXML());
		
	}

	public class PraseXML extends DefaultHandler {

		private Vector<String> tagName;

		private Vector<String> tagValue;

		private int step;

		// 开始解析XML文件
		public void startDocument() throws SAXException {
			tagName = new Vector<String>();
			tagValue = new Vector<String>();
			step = 0;
		}

		// 结束解析XML文件
		public void endDocument() throws SAXException {
			for (int i = 0; i < tagName.size(); i++) {
				if (!tagName.get(i).equals("") || tagName.get(i) != null) {
					System.out.println("节点名称:" + tagName.get(i));
					System.out.println("节点值:" + tagValue.get(i));
				}
			}
		}

		public void startElement(String uri, String localName, String qName,
				Attributes attributes) throws SAXException {
			// 节点名称
			tagName.add(qName);
			// 循环输出属性
			for (int i = 0; i < attributes.getLength(); i++) {
				// 获取属性名称
				System.out.println("属性名称:" + attributes.getQName(i));
				// 获取属性值
				System.out.println("属性值:"
						+ attributes.getValue(attributes.getQName(i)));
			}

		}

		/**
		 * 在遇到结束标签时调用此方法
		 */
		public void endElement(String uri, String localName, String qName)
				throws SAXException {

			step = step + 1;
		}

		/**
		 * 读取标签里的值,ch用来存放某行的xml的字符数据,包括标签,初始大小是2048, 每解释到新的字符会把它添加到char[]里。 *
		 * 注意,这个char字符会自己管理存储的字符, 并不是每一行就会刷新一次char,start,length是由xml的元素数据确定的,
		 * 暂时找不到规律,以后看源代码.
		 * 
		 * 这里一个正标签,反标签都会被执行一次characters,所以在反标签时不用获得其中的值
		 */
		public void characters(char ch[], int start, int length)
				throws SAXException {
			// 只要当前的标签组的长度一至,值就不赋,则反标签不被计划在内
			if (tagName.size() - 1 == tagValue.size()) {
				tagValue.add(new String(ch, start, length));
			}
		}

		public Vector getTagName() {
			return tagName;
		}

		public void setTagName(Vector tagName) {
			this.tagName = tagName;
		}

		public Vector getTagValue() {
			return tagValue;
		}

		public void setTagValue(Vector tagValue) {
			this.tagValue = tagValue;
		}

	}

第三种JDOM

第四种DOM4J




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值