Java使用XPath提取XML节点并封装为自定义类列表的优化方法
方案1:基于单游戏节点上下文查询(易读性优先)
不需要每次都从根节点扫描整个文档,直接以遍历到的每个游戏节点为上下文执行相对路径查询,虽然还是3次XPath调用,但都是在当前节点的子节点中查询,性能远高于原有的全文档扫描,而且代码逻辑清晰不易出错。
首先定义你需要的Probability类:
public class Probability { private double team1WinPerc; private double team2WinPerc; private double drawPerc; // 构造方法 public Probability(double team1WinPerc, double team2WinPerc, double drawPerc) { this.team1WinPerc = team1WinPerc; this.team2WinPerc = team2WinPerc; this.drawPerc = drawPerc; } // 按需添加getter、setter方法 }
优化后的业务代码:
final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); final DocumentBuilder db = dbf.newDocumentBuilder(); final Document document = db.parse(new InputSource( new ByteArrayInputStream(xmlResponseString.getBytes(StandardCharsets.UTF_8)))); final XPathFactory xpathFactory = XPathFactory.newInstance(); final XPath xpath = xpathFactory.newXPath(); // 拿到所有游戏节点 NodeList gameNodes = (NodeList) xpath.evaluate("stats/games/*", document, XPathConstants.NODESET); List<Probability> probabilityList = new ArrayList<>(gameNodes.getLength()); for (int i = 0; i < gameNodes.getLength(); i++) { Node gameNode = gameNodes.item(i); // 直接在当前游戏节点下查询相对路径,不需要拼接节点名 double team1Win = Double.parseDouble(xpath.evaluate("team1_win_perc", gameNode, XPathConstants.STRING)); double team2Win = Double.parseDouble(xpath.evaluate("team2_win_perc", gameNode, XPathConstants.STRING)); double draw = Double.parseDouble(xpath.evaluate("draw_perc", gameNode, XPathConstants.STRING)); probabilityList.add(new Probability(team1Win, team2Win, draw)); }
方案2:单次XPath查询所有目标节点(性能优先)
如果你需要彻底避免多次XPath调用,可以直接写一个XPath表达式一次性取出所有游戏的三个百分比节点,每三个节点为一组对应一个游戏的三个值,全程只执行一次XPath评估:
final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); final DocumentBuilder db = dbf.newDocumentBuilder(); final Document document = db.parse(new InputSource( new ByteArrayInputStream(xmlResponseString.getBytes(StandardCharsets.UTF_8)))); final XPathFactory xpathFactory = XPathFactory.newInstance(); final XPath xpath = xpathFactory.newXPath(); // 一次性查询所有游戏下的三个百分比节点,顺序和XML中节点顺序一致 NodeList percNodes = (NodeList) xpath.evaluate("stats/games/*/team1_win_perc | stats/games/*/team2_win_perc | stats/games/*/draw_perc", document, XPathConstants.NODESET); List<Probability> probabilityList = new ArrayList<>(); // 每三个节点对应一个游戏的三个值 for (int i = 0; i < percNodes.getLength(); i += 3) { double team1Win = Double.parseDouble(percNodes.item(i).getTextContent()); double team2Win = Double.parseDouble(percNodes.item(i+1).getTextContent()); double draw = Double.parseDouble(percNodes.item(i+2).getTextContent()); probabilityList.add(new Probability(team1Win, team2Win, draw)); }
注意:该方案依赖XML中每个游戏节点下的三个百分比节点顺序固定为
team1_win_perc->team2_win_perc->draw_perc,如果你的XML结构顺序可能变化,推荐使用方案1。
内容的提问来源于stack exchange,提问作者clattenburg cake
相关产品推荐
相关产品推荐

