需求说明:
使用 dom4j 解析上一节王者荣耀“英雄”对应的Xml文件数据内容,打印输出,具体格式如图所示
实现思路:
创建ParseHeroXML用于解析Xml,创建Hero类用于封装解析的英雄对象数据
在ParseHeroXML中定义parse()解析方法,根据讲解SAXReader进行解析Xml文件,获取根节点,定义listNodes递归方法调用,传入根节点
在listNodes方法中,遍历节点信息,分别根据节点名称获取相关节点的属性,遇到hero节点时,代表是一个英雄信息, 创建Hero实体对象,存储至List集合中,然后调用获取子节点信息方法getAttrAndChildNode
getAttrAndChildNode为获取hero子节点下的信息的方法,该方法中,获取属性判断是name或id,存储至Hero对象中,继续遍历子节点递归调用
循环遍历List集合中的Hero对象信息,输出查看
实现代码:
用于解析Xml的ParseHeroXML类
import java.io.File; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.dom4j.Attribute; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Element; import org.dom4j.io.SAXReader; public class ParserHeroXML { Document document = null; Element rootElement = null; Hero hero = null; // 用来保存所有的英雄数据 List<Hero> heros = new ArrayList<>(); // 解析XML文档 public void parse() { try { // 创建saxReader对象 SAXReader reader = new SAXReader(); // 通过read方法读取一个文件,转换成Document对象 document = reader.read(new File("H:/hero.xml")); // 获取根节点元素对象 rootElement = document.getRootElement(); // 遍历所有的元素节点 listNodes(rootElement); } catch (DocumentException e) { e.printStackTrace(); } } // 递归遍历节点信息 public void listNodes(Element element) { // 获取节点名称 String elementName = element.getName(); // 获取节点的文本 String elementText = element.getTextTrim(); // 判断当前的节点名称 switch (elementName) { case "hero": hero = new Hero(); heros.add(hero); getAttrAndChildNode(element); break; case "gender": hero.setGender(elementText); break; case "profession": hero.setProfession(elementText); break; case "nationality": hero.setNationality(elementText); break; case "price": hero.setPrice(Double.parseDouble(elementText)); break; case "heroList": getAttrAndChildNode(element); break; default: break; } } // 获取节点上的属性值和子节点对象 public void getAttrAndChildNode(Element element) { // 获取节点的所有属性 List<Attribute> attributes = element.attributes(); Attribute attr = null; String attrValue = null; // 循环遍历节点的每个属性 for (int i = 0; i < attributes.size(); i++) { // 获取节点中的每个属性 attr = attributes.get(i); // 获取每个属性所对应的值 attrValue = attr.getValue(); // 判断是否是id节点还是name节点 if ("id".equals(attr.getName())) { // 将id的值保存到hero对象内 hero.setId(Integer.parseInt(attrValue)); } else if ("name".equals(attr.getName())) { // 将name的值保存到hero对象内 hero.setName(attrValue); } } // 获取当前节点下的所有子节点 Iterator<Element> eleIterator = element.elementIterator(); // 判断该节点下是否还有子节点 while (eleIterator.hasNext()) { // 取出子节点 Element e = eleIterator.next(); // 递归遍历子节点的信息 listNodes(e); } } // 遍历保存到集合中的英雄信息 public void showHeroInfo() { for (Hero tempHero : heros) { System.out.printf("编号:%d,姓名:%s,性别:%s,职业:%s,国籍:%s,价格:%.2f\n", tempHero.getId(), tempHero.getName(), tempHero.getGender(), tempHero.getProfession(), tempHero.getNationality(), tempHero.getPrice()); } } public static void main(String[] args) { ParserHeroXML parserHeroXML = new ParserHeroXML(); parserHeroXML.parse(); parserHeroXML.showHeroInfo(); } }
用于封装解析的英雄对象数据Hero类
public class Hero { private int id;// 英雄编号 private String name;// 英雄名称 private String gender;// 英雄性别 private String profession;// 英雄职业 private String nationality;// 英雄国籍 private double price; // 出售价格 public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } public String getProfession() { return profession; } public void setProfession(String profession) { this.profession = profession; } public String getNationality() { return nationality; } public void setNationality(String nationality) { this.nationality = nationality; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } }