Java读取欧洲央行在线XML汇率文件并提取汇率至数组
简化ECB汇率XML的提取逻辑
嘿,我明白你想简化汇率提取的需求——ECB的这个XML结构确实有几层嵌套的Cube节点,直接遍历所有Cube会拿到很多无关的节点(比如顶层的Cube和带日期的Cube),所以咱们可以用XPath来精准定位目标节点,既简便又能保证原始顺序。
首先先理清ECB这个XML的结构:
它的层级是:顶层
<Cube>→ 带时间属性的<Cube time="...">→ 每个汇率对应的<Cube currency="USD" rate="1.0923"/>(这才是我们要的节点)
所以我们可以直接用XPath表达式定位到所有带currency和rate属性的Cube节点,这样就能跳过外层无关的节点,直接拿到汇率数据。
下面是改进后的代码,我会一步步说明:
import org.w3c.dom.Document; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.InputSource; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathFactory; import java.net.URL; import java.util.ArrayList; import java.util.List; public class CurrencyConverter { public static void main(String[] args) { // 定义存储汇率的列表(天然保持文档顺序) List<Rate> rates = new ArrayList<>(); try { URL url = new URL("http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml"); Document doc = DocumentBuilderFactory.newInstance() .newDocumentBuilder() .parse(new InputSource(url.openStream())); doc.getDocumentElement().normalize(); // 初始化XPath工具 XPath xpath = XPathFactory.newInstance().newXPath(); // XPath表达式:精准匹配所有带currency和rate属性的Cube节点 String xpathExpr = "//Cube[@currency and @rate]"; NodeList rateNodes = (NodeList) xpath.evaluate(xpathExpr, doc, javax.xml.xpath.XPathConstants.NODESET); // 遍历节点提取数据 for (int i = 0; i < rateNodes.getLength(); i++) { Node node = rateNodes.item(i); String currency = node.getAttributes().getNamedItem("currency").getNodeValue(); double rate = Double.parseDouble(node.getAttributes().getNamedItem("rate").getNodeValue()); // 存入自定义对象,方便后续使用 rates.add(new Rate(currency, rate)); } // 测试输出验证结果 for (Rate rate : rates) { System.out.println(rate.getCurrency() + ": " + rate.getRate()); } } catch (Exception e) { // 不要空catch块,打印异常信息方便调试 e.printStackTrace(); } } // 自定义简单类存储货币-汇率对 static class Rate { private String currency; private double rate; public Rate(String currency, double rate) { this.currency = currency; this.rate = rate; } public String getCurrency() { return currency; } public double getRate() { return rate; } } }
核心优化点:
- XPath精准定位:
//Cube[@currency and @rate]会严格按照XML文档的原始顺序返回所有目标节点,完全符合你“按原始顺序提取”的需求,不用再手动过滤无关节点。 - 灵活的数据存储:用
ArrayList<Rate>比普通数组更易扩展,如果你需要转成数组,直接调用rates.toArray(new Rate[0])即可;如果不想自定义类,也可以用List<String[]>存储[货币代码, 汇率值]的数组对。 - 实用的异常处理:替换了空catch块,打印异常栈信息,能帮你快速排查网络问题、XML解析错误等潜在问题。
这样是不是比遍历所有Cube节点要简便清晰很多?直接一步到位拿到你需要的汇率数据~
内容的提问来源于stack exchange,提问作者SBozhko
相关产品推荐
相关产品推荐

