多种技术解析xml文件
前言
使用框架的时候,xml配置文件是如何进行解析的?你是否有同样的疑问,今天我就带你一文搞定xml文件的解析。
我们针对不同内容的xml文件采取不同的方式解析
正文
方式一:使用SAX解析xml
对于web.xml类似这种的文件格式(如下),节点中没有属性我们使用SAX的方式进行解析
<servlet>
<servlet-name>login</servlet-name>
<servlet-class>tjoker.servlet.LoginWeb</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>login</servlet-name>
<url-pattern>/g</url-pattern>
<url-pattern>/y</url-pattern>
</servlet-mapping>
实现
public class WebHandler extends DefaultHandler {
private static final String filepath="web.xml";
private List<Entity> entityList;//Entity 定义的实体类
private List<Mapping> mappingList;//Mapping 定义的实体类
private Entity entity;
private Mapping mapping;
private boolean isMapping;//判断是否是mapping
private String tag;//存储操作表示符
@Override
public void startDocument() throws SAXException {
//文档解析开始初始化
entityList=new ArrayList<>();
mappingList=new ArrayList<>();
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
if(qName!=null){
tag=qName;
if(qName.equals("servlet")){
isMapping=false;
entity = new Entity();
}else if(qName.equals("servlet-mapping")){
isMapping=true;
mapping = new Mapping();
}
}
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
if(tag!=null){
String str =new String(ch,start,length).trim();
if(isMapping==false){
if(tag.equals("servlet-name")){
entity.setName(str);
}else if(tag.equals("servlet-class")){
entity.setClz(str);
}
}else {
if(tag.equals("servlet-name")){
mapping.setName(str);
}else if(tag.equals("url-pattern")){
mapping.addPattern(str);
}
}
}
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
if(qName!=null){
if(qName.equals("servlet")){
entityList.add(entity);
}else if(qName.equals("servlet-mapping")){
mappingList.add(mapping);
}
}
tag=null;
}
public static void main(String[] args) throws DocumentException, ParserConfigurationException, SAXException, IOException {
//获取解析工厂
SAXParserFactory factory =SAXParserFactory.newInstance();
//获取解析器
SAXParser sax =factory.newSAXParser();
//指定xml+处理器
WebHandler web = new WebHandler();
sax.parse(Thread.currentThread().getContextClassLoader()
.getResourceAsStream(filepath),web);
}
public List<Entity> getEntityList() {
return entityList;
}
public List<Mapping> getMappingList() {
return mappingList;
}
public Entity getEntity() {
return entity;
}
public Mapping getMapping() {
return mapping;
}
}
方式二:使用dom4j解析文件
对于节点标签中有属性的我们通常采用方式二使用dom4j对文件进行解析,这样避免了方式一重复判断,大量使用if-else的弊端。
<service id="26" name="updateRole" method="updateRole"
class="tjoker.service.UserService">
<result name="success" type="ajax">/role_list.jsp</result>
<result name="failed" type="ajax">/role_list.jsp</result>
</service>
实现
导入jar坐标
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>
解析核心代码
/*
* 使用dom4j解析xml文件
* */
private static String configFile="/service.xml";解析文件地址
public static void parseDom4j() throws ServiceException {
try {
//SAXReader就是一个管道,用一个流的方式将xml读取出来
SAXReader reader=new SAXReader();
//解析路径
URL url = ServiceMapper.class.getResource(configFile);
//解析xml文件,重新构建一个document对象
Document document=reader.read(url);
Element root=document.getRootElement();
List<Element> elementService=root.elements("service");
//使用迭代器输出获取service节点
Iterator it=elementService.iterator();
while (it.hasNext()){
Element element= (Element) it.next();
//对解析到的数据进行存储
int id=Integer.parseInt(element.attributeValue("id"));
String name=element.attributeValue("name");
String method=element.attributeValue("method");
String classStr=element.attributeValue("class");
String operate=element.attributeValue("operate");
//创建serviceConfig对象,存储解析到的数据
ServiceConfig serviceConfig=new ServiceConfig();
//存储数据
serviceConfig.setId(id);
serviceConfig.setName(name);
serviceConfig.setMethodName(method);
serviceConfig.setClassName(classStr);
serviceConfig.setOperate(operate);
}
}catch (DocumentException e){
String msg="使用dom4j解析xml文件失败";
LOGGER.error(msg);
throw new ServiceException(e);
}
}
怎么样,是不是很简单,赶快动手试试