`
剑锋凛冽
  • 浏览: 73429 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论

使用java解析XML

阅读更多

Java本身提供了三种API进行XML文本的解析。

1.DOM:DOM方式解析XML文本时,先分析整个XML,形成XML的DOM树,然后节点列表的方式遍历它。

 

package xmlHandler;

import java.io.File;
import java.io.IOException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
import org.xml.sax.SAXException;

public class DOMParserXml {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
        DOMParserXml domparser=new DOMParserXml();
        domparser.domParserForXML(System.getProperty("user.dir")+"/person.xml");
        domparser.XPathGetValue(System.getProperty("user.dir")+"/person.xml");
	}

	// DOM解析器生成tree,解析过程也必须严格按照tree结构写成循环解析
	public void domParserForXML(String xmlPath) {
		Person person = new Person();// 用于存放解析出的值
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();// 创建XML的DOM工厂
		
		try {
			DocumentBuilder builder = factory.newDocumentBuilder();
			File xmlFile = new File(xmlPath);// 可以用InputStream、URL、File来设置XML来源
			Document doc = builder.parse(xmlFile);// 读入文档,这是一个接口
			Element root = doc.getDocumentElement();// 获取根节点
			System.out.println("根节点名称:" + root.getTagName());
			NodeList children = root.getChildNodes();// 这里的child可以使文本、子元素、其他节点
			for (int i = 0; i < children.getLength(); i++) {
				Node child = children.item(i);
				//使用语句factory.setIgnoringElementContentWhitespace(true);//过滤空白字符,就不需要判断类型了。
				if (child instanceof Element) {// 解析器将标签之间的空格也认为是子元素,用instanceof过滤它们
					
					Element childElement = (Element) child;
					System.out.print("\t子节点名称" + childElement.getTagName());
					System.out.println("\t属性值:"
							+ childElement.getAttribute("sex"));
					//可以通过getAttributes方法获取所有属性值的键值对。
					person.setSex(childElement.getAttribute("sex"));
					NodeList grandsons = childElement.getChildNodes();
					for (int j = 0; j < grandsons.getLength(); j++) {
						Node grandson = grandsons.item(j);
						if (grandson instanceof Element) {
							Element grandElement = (Element) grandson;
							System.out.print("\t\t孙节点名称:"
									+ grandElement.getTagName());
							Text textNode = (Text) grandElement.getFirstChild();
							System.out.println("\t孙节点文本值:"
									+ textNode.getData().trim());
							if (grandElement.getTagName().equals("name")) {
								person.setName(textNode.getData().trim());
							}
							if (grandElement.getTagName().equals("description")) {
								person
										.setDescription(textNode.getData()
												.trim());
							}
						}
					}
				}
			}
		} 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();
		}
		System.out.println("解析结果:::" + person.toString());
	}

	
	public void XPathGetValue(String xmlFilePath){
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();// 创建XML的DOM工厂
		try {
			DocumentBuilder builder = factory.newDocumentBuilder();
			File file=new File(xmlFilePath);
			Document doc=builder.parse(file);
			//通过XPath表达式快速访问XML文件的节点及其文本值
			XPathFactory xpathFactory=XPathFactory.newInstance();
			XPath xpath=xpathFactory.newXPath();
			System.out.println("==============使用XPath快速访问XML节点值:");
			String query="/persons/person/name";
			System.out.println(xpath.evaluate(query, doc));
			
		} 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 (XPathExpressionException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

 2.SAXParser使用事件流驱动的方式进行XML文本的解析。

 

package xmlHandler;

import java.io.File;
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;

public class SAXParserXML {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		SAXParserFactory factory = SAXParserFactory.newInstance();
		try {
			SAXParser parser = factory.newSAXParser();
			File file = new File(System.getProperty("user.dir") + "/person.xml");
			parser.parse(file, new PersonXMLHandler());// 此处的file可以使文件、输入流、或URL字符串
		} 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();
		}

	}

}

class PersonXMLHandler extends DefaultHandler {
	Person person;
	String temp = "";
	String currenttag = null;

	@Override
	public void characters(char[] ch, int start, int length)
			throws SAXException {
		// TODO Auto-generated method stub
		if (currenttag != null) {
			String value = new String(ch, start, length);
			if (currenttag.equals("name")) {
				person.setName(value);
			}
			if (currenttag.equals("description")) {
				temp += value;// 处理长文本
			}
		}
	}

	@Override
	public void endDocument() throws SAXException {
		// TODO Auto-generated method stub
		super.endDocument();
	}

	@Override
	public void endElement(String uri, String localName, String qName)
			throws SAXException {
		// TODO Auto-generated method stub
		currenttag=null;
		if (qName.endsWith("description")) {
			person.setDescription(temp);
			temp = "";
		}
		if (qName.endsWith("person"))
			System.out.println("当前解析出的结果:" + person.toString());
	}

	@Override
	public void startDocument() throws SAXException {
		// TODO Auto-generated method stub
		super.startDocument();
	}

	@Override
	public void startElement(String uri, String localName, String qName,
			Attributes attributes) throws SAXException {
		// TODO Auto-generated method stub
		if (qName.equals("person")) {
			person = new Person();
			person.setSex(attributes.getValue("sex"));
		}
		currenttag = qName;
	}

}

 3,StAX同样也是事件流驱动的解析器,只是不再进行startElement、characters的区分。

 

package xmlHandler;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;

import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;

public class StAXParserXML {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
        StAXParserXML parser=new StAXParserXML();
        parser.StAXParser(System.getProperty("user.dir") + "/person.xml");
	}

	// StAXParser 是一种“pull parser”,允许通过循环来迭代访问所有事件
	public void StAXParser(String xmlPath) {
		XMLInputFactory factory = XMLInputFactory.newInstance();
		Person person=new Person();
		File file = new File(xmlPath);
		try {
			//参数必须是InputStream类型,可以是File的包装器、URL打开的InputStream
			XMLStreamReader parser = factory
					.createXMLStreamReader(new FileInputStream(file));
			// parser遍历xml文档时产生一系列事件
			while (parser.hasNext()) {
				int event = parser.next();// 获取当前event
				if (event == XMLStreamConstants.START_ELEMENT) {//如果是element
					if (parser.getLocalName().equals("person")) {//判断标签值
						person.setSex(parser.getAttributeValue(0));//获取属性值
					}
					if(parser.getLocalName().equals("name")){
						person.setName(parser.getElementText());//获取元素文本
					}
					if(parser.getLocalName().equals("description")){
						person.setDescription(parser.getElementText());
					}
				}
			}
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (XMLStreamException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}// 这里的参数只能是InputStream
		System.out.println(person.toString());
	}

}

 具体的参见源代码就行了

分享到:
评论
2 楼 剑锋凛冽 2012-07-02  
cuisuqiang 写道
java解析xml有多种方式,目前jdk6已经包含了pull解析,可以学习一下去

多谢关注,我在文章里已经写过,StAX就是一种pull解析器,它允许只解析一部分内容就直接终止对整个文件的事件流访问,而SAX不能这样,必须完成整个文档的事件触发才能结束
1 楼 cuisuqiang 2012-06-29  
java解析xml有多种方式,目前jdk6已经包含了pull解析,可以学习一下去

相关推荐

Global site tag (gtag.js) - Google Analytics