Java sax解析xml

本文介绍使用SAX解析XML文件的方法,通过示例代码展示了如何解析特定节点,并将节点属性存储到对象中以供后续处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        新项目里面解析xml需要sax,就查了下资料,顺便写点加强理解。xml中有两种节点,一种是ElementNode,比如下面的一个简单的xml文件中的<SkillInfo>和<skill>等,另一种是TextNode,是节点之间的文本(例如<name>测试解析xml</name>中的测试解析xml就是TextNode)。

       sax解析器是将xml文件按照顺序依次载入,当读到<SkillInfo>这些Element节点时,就会调用startElemt(……)方法,节点之间的空白sax解析器认为是TextNode节点,只是是空的,节点之间的文本会调用characters(……)方法,不过本文没用到。当解析到</……>这种标签时,会调用endElement(……)方法。

       看看如下简单xml文件的解析代码,将<skill>节点的数据放到map中保存,id为key,value是一个类对象,类中含有属性id,addtional和name。


xml文件:

<?xml version="1.0" encoding="UTF-8"?>

<SkillInfo>
	<skill id="1" addtional="攻击目标数最多可升阶至7个" name="虎啸">
		<upgrade>
			<node level="0" desc="升阶提升技能攻击范围和目标数">
				<effect type="1" effect="208"/>
			</node>
		</upgrade>
	</skill>
</SkillInfo>

java代码:

import javax.xml.parsers.*;

import org.xml.sax.*;
import org.xml.sax.helpers.DefaultHandler;

import java.util.*;


public class TestJavaSax extends DefaultHandler {
	
	/**
	 * 解析时ElementNode调用startElement,
	 * @param qName就是节点名
	 * @param attr就是对应标签的所有属性,通过attr.getValue("属性名")取得属性数据
	 */
	public void startElement(String namespaceURI, String localName, String qName, Attributes attr ) throws SAXException {
		
		if ("skill_info".equals(qName)) {
			//……
		}
		else if ("skill".equals(qName)) {
			
			//_tmpSkillItem保存相应标签的属性值
			_tmpSkillItem = new SkillItem();							
			_tmpSkillItem.setId(Integer.parseInt(attr.getValue("id")));
			_tmpSkillItem.setAddtional(attr.getValue("addtional"));
			_tmpSkillItem.setName(attr.getValue("name"));
		}
		else if ("upgrade".equals(qName)) {
			//……
		} 
		else if ("node".equals(qName)) {
			_tmpNodeItem = new NodeItem();
			_tmpNodeItem.setLevel(Integer.parseInt(attr.getValue("level")));
			_tmpNodeItem.setDesc(attr.getValue("desc"));
		}
		else if ("effect".equals(qName)) {
			//……
		}
 	}

	/**
	 * 解析TextNode时回调,此次没用到
	 */
	public void characters( char[] chars, int start, int length ) throws SAXException {
        //……
    }
	
	/**
	 * 遇到结束标签时回调
	 * @param qName是标签名
	 */
	public void endElement( String namespaceURI, String localName, String qName ) throws SAXException {

		if ("skill_info".equals(qName)) {
			//……
		}
		else if ("skill".equals(qName)) {
			skillDict.put(_tmpSkillItem.getId(), _tmpSkillItem);		//将属性对象放到map中
			_tmpSkillItem = null;										//去掉不必要的引用
		}
		else if ("upgrade".equals(qName)) {
			//……
		}
		else if ("node".equals(qName)) {
			//……
			_tmpNodeItem = null;
		}
	}
	
	public static TestJavaSax getInstance() {
		if (null == saxInstance) {
			saxInstance = new TestJavaSax();
			
			//实例化用于分析的工厂
			SAXParserFactory factory = SAXParserFactory.newInstance();
			try {
				//实例化分析类
				SAXParser parser = factory.newSAXParser();
				
				//xml路径
				String path = "skill_info.xml";
				
				parser.parse(path, saxInstance);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		
		return saxInstance;
	}
	
	public static void main(String[] args) {
		
		TestJavaSax saxInstance = TestJavaSax.getInstance();
		
		Iterator iter = skillDict.entrySet().iterator();
		while (iter.hasNext()) {
			Map.Entry entry = (Map.Entry) iter.next();
			SkillItem tmpClass = new SkillItem();
			tmpClass = (SkillItem)entry.getValue();
			System.out.print("key:" + entry.getKey() + "  ");
			System.out.println("value:" + tmpClass.getId() + ", " + tmpClass.getAddtional() + ", " + tmpClass.getName());
		}
	}
	
	
	private static TestJavaSax saxInstance = null;
	private SkillItem _tmpSkillItem = null;
	private NodeItem _tmpNodeItem = null;
	private static Map<Integer, SkillItem> skillDict = new HashMap<Integer, SkillItem>(); 
}

/**
 * SkillItem保存属性值
 */
class SkillItem {
	
	public void setId(int id) {
		this.id = id;
	}
	
	public int getId() {
		return id;
	}
	
	public void setAddtional(String addtional) {
		this.addtional = addtional;
	}
	
	public String getAddtional() {
		return addtional;
	}
	
	public void setName(String name) {
		this.name = name;
	}
	
	public String getName() {
		return name;
	}
	
	private int id;
	private String addtional;
	private String name;
}

class NodeItem {
	
	public void setLevel(int level) {
		this.level = level;
	}
	
	public int getLevel() {
		return level;
	}
	
	public void setDesc(String desc) {
		this.desc = desc;
	}
	
	public String getDesc() {
		return desc;
	}

	private int level;
	private String desc;
}


控制台打印的部分解析结果:

key:1  value:1, 攻击目标数最多可升阶至7个, 虎啸

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值