使用SAX解析xml文件

解析xml文件有好几种方法,包括有:Dom、Jdom、SAX解析、Demo4j 等等

本篇主要讲解SAX是如何解析xml文件的。


项目结构如下:


新建一个ParserUtil类,继承自DefaultHandler,并重写五个方法:startDocument()、startElement、characters()、endElement、endDocument()

public class ParserUtil extends DefaultHandler{
	
	//开始xml解析时调用
	@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
		super.startElement(uri, localName, qName, attributes);
	}

	//获取节点内容时调用
	@Override
	public void characters(char[] ch, int start, int length) throws SAXException {
		// TODO Auto-generated method stub
		super.characters(ch, start, length);
	}
	
	//完成某个节点解析时调用
	@Override
	public void endElement(String uri, String localName, String qName) throws SAXException {
		// TODO Auto-generated method stub
		super.endElement(uri, localName, qName);
	}
	
	//完成整个xml解析时调用
	@Override
	public void endDocument() throws SAXException {
		// TODO Auto-generated method stub
		super.endDocument();
	}
}


在项目下创建一个data.xml文件,作为解析源使用:

像<Users>、<user>这种结构的xml文件称为ElementNode

<?xml version="1.0" encoding="UTF-8"?>
<Users>
<user>
	<id>1</id>
	<name>Tom</name>
	<age>21</age>
</user>
<user>
	<id>2</id>
	<name>Jerry</name>
	<age>20</age>
</user>
<user>
	<id>3</id>
	<name>Iris</name>
	<age>22</age>
</user>
</Users>

根据data.xml的构成方式,ParserUtil重写父类方法的具体实现如下:

public class ParserUtil extends DefaultHandler{
	
	private String nodeName;
	private StringBuilder id;
	private StringBuilder name;
	private StringBuilder age;
	
	@Override
	public void startDocument() throws SAXException {
		System.out.println("***开始解析***");
		id = new StringBuilder();
		name = new StringBuilder();
		age = new StringBuilder();
	}

	@Override
	public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
		//记录节点名
		nodeName = qName;
	}
	
	@Override
	public void characters(char[] ch, int start, int length) throws SAXException {
		//根据当前节点名判断将内容添加到哪一个对象中
		if (nodeName.equals("id")) {
			id.append(ch,start,length);
		}else if (nodeName.equals("name")) {
			name.append(ch, start, length);
		}else if (nodeName.equals("age")) {
			age.append(ch, start, length);
		}
	}
	
	@Override
	public void endElement(String uri, String localName, String qName) throws SAXException {
		if (qName.equals("user")) {
			System.out.println("id:"+id.toString().trim());
			System.out.println("name:"+name.toString().trim());
			System.out.println("age:"+age.toString().trim());
			
			id.setLength(0);
			name.setLength(0);
			age.setLength(0);
		}
	}
	
	@Override
	public void endDocument() throws SAXException {
		System.out.println("***解析完成***");

	}
}

SAXParser类:

public class SAXpaser{
	
	/**
	 * 获取本地xml文件数据
	 * @param args
	 */
	public static String getXMLData(){
		try {
			InputStream is = new FileInputStream(new File("WebContent/data.xml"));
			BufferedReader br = new BufferedReader(new InputStreamReader(is));
			String line = "";
			StringBuilder sb = new StringBuilder();
			while((line=br.readLine())!=null){
				sb.append(line).append("\n");
			}
			is.close();
			br.close();
			return sb.toString();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}
	
	/**
	 * 使用SAX解析xml文件
	 * @param args
	 */
	public static void parserXMLWtihSAX(String xmlData){
		SAXParserFactory factory = SAXParserFactory.newInstance();
		try {
			XMLReader xmlReader = factory.newSAXParser().getXMLReader();
			ParserUtil parserUtil = new ParserUtil();
			xmlReader.setContentHandler(parserUtil);
			xmlReader.parse(new InputSource(new StringReader(xmlData)));
		} catch (SAXException | ParserConfigurationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public static void main(String[] args) {
		String xmlData = getXMLData();
		parserXMLWtihSAX(xmlData);
		
	}

}


程序运行结果:

***开始解析***
id:1
name:Tom
age:21
id:2
name:Jerry
age:20
id:3
name:Iris
age:22
***解析完成***

注意:在解析xml过程博主遇到了一个奇怪的问题,startElement()、endElement()方法中,通过localName匹配节点名称失败,通过System.out.println(localName)查看,结果什么都没输出。在网上搜索一通之后,终于找到问题了,原因是不同计算机的运行环境有可能不一样,导致localName的值为空。如果通过localName获取不到解析结果,请尝试使用qName匹配节点名称,获取解析结果。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在Java中使用SAX解析XML,你可以按照以下步骤进行操作: 1. 导入相关的类和包,如`javax.xml.parsers.SAXParser`和`javax.xml.parsers.SAXParserFactory`。 2. 创建`SAXParserFactory`的实例。 3. 通过调用`SAXParserFactory`的`newSAXParser()`方法创建一个解析器。 4. 获取需要解析的XML文档,并创建一个`File`对象来表示该文档。 5. 创建一个自定义的`SAXHandler`类,该类继承自`DefaultHandler`类,并重写需要的回调方法来处理XML元素和数据。 6. 调用解析器的`parse()`方法,传入文件和自定义的`SAXHandler`对象作为参数,开始解析XML文档。 你可以参考以下示例代码: ```java import java.io.File; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; public class TestDemo { public static void main(String[] args) throws Exception { // 1.实例化SAXParserFactory对象 SAXParserFactory factory = SAXParserFactory.newInstance(); // 2.创建解析SAXParser parser = factory.newSAXParser(); // 3.获取需要解析的文档,生成解析器,最后解析文档 File f = new File("books.xml"); SaxHandler dh = new SaxHandler(); parser.parse(f, dh); } } ``` 请注意,上述代码中的`SaxHandler`是一个自定义的类,你需要根据自己的需求来实现该类,以便在解析XML时处理相应的元素和数据。 XML文档如下所示: ```xml <?xml version="1.0" encoding="UTF-8"?> <books> <book id="001"> <title>Harry Potter</title> <author>J K. Rowling</author> </book> <book id="002"> <title>Learning XML</title> <author>Erik T. Ray</author> </book> </books> ``` 希望以上信息能够帮到你。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [java中使用sax解析xml的解决方法](https://download.csdn.net/download/weixin_38747216/12815749)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [在java中使用sax解析xml](https://blog.csdn.net/weixin_33884611/article/details/86303531)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值