Java for循环从xml文档中获取子元素
Java for loop to obtain child elements from xml document
为了简单起见,我很难弄清楚如何编写一个循环来从给定的 XML 文档中检索值我会给你一个 xml
文件的示例
</solution>
<solution>
<cost>505.9208295302417</cost>
<routes>
<route>
<driverId>noDriver</driverId>
<vehicleId>1_1</vehicleId>
<start>0.0</start>
<act type="service">
<serviceId>5 </serviceId>
<arrTime>109.9819741964403</arrTime>
<endTime>119.9819741964403</endTime>
</act>
<end>229.9639483928806</end>
</route>
<route>
<driverId>noDriver</driverId>
<vehicleId>3_1</vehicleId>
<start>0.0</start>
<act type="service">
<serviceId>4 </serviceId>
<arrTime>109.98190391287031</arrTime>
<endTime>119.98190391287031</endTime>
</act>
<act type="service">
<serviceId>2 </serviceId>
<arrTime>119.98282618841856</arrTime>
<endTime>129.98282618841856</endTime>
</act>
<act type="service">
<serviceId>1 </serviceId>
<arrTime>129.98372097890456</arrTime>
<endTime>139.98372097890456</endTime>
</act>
<act type="service">
<serviceId>3 </serviceId>
<arrTime>139.9846432544528</arrTime>
<endTime>149.9846432544528</endTime>
</act>
<end>259.9668316441239</end>
</route>
</routes>
</solution>
</solutions>
基本上我在代码中向您展示的是仅从成本 = 505.9208295302417 的节点获取值,请不要考虑这部分代码,所以下一步是检索 driverid``, vehicleid and
act ,我知道缺少 for 循环但我不知道放在哪里!!请有人帮忙。我需要的期望输出就像每个 vehicleid
获取与其关联的列表行为值
java代码
public static void main(String[] args) {
try {
int totalVehicle;
totalVehicle = 2;
File fXmlFile = new File("C:/Users/HP/Desktop/solution.xml");
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(fXmlFile);
doc.getDocumentElement().normalize();
Double requiredCost = 505.9208295302417;
System.out.println("Root element :" + doc.getDocumentElement().getNodeName());
// NodeList nList = doc.getElementsByTagName("route");
System.out.println("----------------------------");
NodeList nodeList = doc.getElementsByTagName("solution");
for (int i = 0; i < nodeList.getLength(); i++) {
Node solutionNode = nodeList.item(i);
if (solutionNode.getNodeType() == Node.ELEMENT_NODE) {
Element solutionElement = (Element) solutionNode;
Node costNode = solutionElement.getElementsByTagName("cost").item(0);
Node route = solutionElement.getElementsByTagName("routes").item(0);
// if correct cost, proceed to parse further
Double costValue = Double.valueOf(costNode.getTextContent());
if (Double.compare(requiredCost, costValue) == 0) {
System.out.println("working");
// there you go, found the node with the cost 505.9208295302417
// now just parse all the node elements you need here
System.out.println("cost : "
+ solutionElement.getElementsByTagName("cost")
.item(0).getTextContent());
for (int h = 0; h < totalVehicle; h++) {
System.out.println("DriverId : "
+ solutionElement.getElementsByTagName("driverId")
.item(h).getTextContent().toString());
System.out.println("vehicleId : "
+ solutionElement.getElementsByTagName("vehicleId")
.item(h).getTextContent());
NodeList optionList = solutionElement.getElementsByTagName("act");
System.out.println(optionList.getLength());
for (int j = 0; j < optionList.getLength(); ++j)
{
for(int k =0;k<1;++k){
Element option = (Element) optionList.item(j);
String optionText = option.getTextContent();
//address.add(optionText.replaceAll("[^A-Za-z]"," "));
System.out.println("Citizen :"+optionText.replaceAll("[^A-Za-z]"," "));}
;
}
正如其他人所建议的那样,使用 xpath 会容易得多,但是如果您绝对需要遍历所有这些东西,请将问题分解成更小、更易于管理的部分。我想我会试一试,我有一个完整的、有效的解决方案来解决你的问题。
我们的想法是将 xml 分解为 Java 个对象并使用这些对象来完成您需要的工作。
public static void main(String... args) throws SAXException, IOException, ParserConfigurationException {
Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder()
.parse(new File("/home/william/Documents/test.xml"));
doc.getDocumentElement().normalize();
NodeList nodeList = doc.getElementsByTagName("solution");
for (int i = 0; i < nodeList.getLength(); i++) {
Node solutionNode = nodeList.item(i);
try {
System.out.println(Solution.newInstance(solutionNode).toString());
} catch (Exception e) {
// do something
e.printStackTrace();
}
}
}
在这里,您的原始文档的解析方式与您执行的方式相同,但解决方案是它自己的 class 您可以将逻辑放入:
public class Solution {
private final double cost;
private final Collection<Route> routes;
public static final Solution newInstance(Node solution) throws Exception {
return new Solution(solution);
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("solution:");
sb.append(System.lineSeparator());
sb.append("--------");
sb.append(System.lineSeparator());
sb.append("cost:");
sb.append(this.cost);
for (Route route : this.routes) {
sb.append(route.toString());
}
return sb.toString();
}
private Solution(Node solution) throws Exception {
if (solution.getNodeType() == Node.ELEMENT_NODE) {
Element solutionElement = (Element) solution;
this.cost = Double.valueOf(solutionElement.getElementsByTagName("cost").item(0).getTextContent());
this.routes = Routes.get(solutionElement.getElementsByTagName("routes").item(0));
} else {
// TODO something?
this.cost = 0D;
this.routes = Collections.emptyList();
}
}
}
请注意,在您的 main
方法中,您可以检查成本。我已经离开了所有 class 变量 getter 方法,如果您需要从对象外部读取它们,请添加您需要的方法。因此,例如在您的 Solution
class 中添加一个 getCost()
方法,然后在 main
方法中您可以适当地检查:if (solution.getCost() == requiredCost) {
...
在这里,根据您的要求,如果需要,您可以将 getter 添加到 class 成员中。我刚刚覆盖了 toString()
方法以打印您可以阅读的内容。
Routes
是一个实用程序 class,用于从 <routes>
节点的子节点中创建 Route
对象的集合。
public class Routes {
private final Collection<Route> items;
public static Collection<Route> get(Node routes) throws Exception {
return new Routes(routes).items;
}
private Routes() {
this.items = new ArrayList<>();
}
private Routes(Node routes) throws Exception {
this.items = new ArrayList<>();
NodeList routesList = routes.getChildNodes();
for (int i = 0; i < routesList.getLength(); i++) {
Node route = routesList.item(i);
if (Node.ELEMENT_NODE == route.getNodeType()) {
items.add(Route.newInstance(route));
} else {
// TODO something?
}
}
}
}
Acts
class 与 Routes
class 具有相似的逻辑(同样的事情,但对于行为):
public class Acts {
private Collection<Act> items;
public static Collection<Act> get(NodeList acts) throws Exception {
return new Acts(acts).items;
}
private Acts() {
this.items = new ArrayList<>();
}
private Acts(NodeList acts) throws Exception {
this.items = new ArrayList<>();
for (int i = 0; i < acts.getLength(); i++) {
Node act = acts.item(i);
if (Node.ELEMENT_NODE == act.getNodeType()) {
this.items.add(Act.newInstance(act));
} else {
// TODO something?
}
}
}
}
最后,每个人 Act
:
public class Act {
private final String service;
private final double arrTime;
private final double endTime;
public static Act newInstance(Node act) throws Exception {
return new Act(act);
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("Act");
sb.append(System.lineSeparator());
sb.append("arr time");
sb.append(System.lineSeparator());
sb.append(this.arrTime);
sb.append(System.lineSeparator());
sb.append("end time:");
sb.append(System.lineSeparator());
sb.append(this.endTime);
sb.append(System.lineSeparator());
sb.append("service:");
sb.append(System.lineSeparator());
sb.append(this.service);
return sb.toString();
}
private Act(Node act) throws Exception {
Element actElement = (Element) act;
this.service = actElement.getAttribute("service");
this.arrTime = Double.valueOf(actElement.getElementsByTagName("arrTime").item(0).getTextContent());
this.endTime = Double.valueOf(actElement.getElementsByTagName("endTime").item(0).getTextContent());
}
}
为了简单起见,我很难弄清楚如何编写一个循环来从给定的 XML 文档中检索值我会给你一个 xml
文件的示例
</solution>
<solution>
<cost>505.9208295302417</cost>
<routes>
<route>
<driverId>noDriver</driverId>
<vehicleId>1_1</vehicleId>
<start>0.0</start>
<act type="service">
<serviceId>5 </serviceId>
<arrTime>109.9819741964403</arrTime>
<endTime>119.9819741964403</endTime>
</act>
<end>229.9639483928806</end>
</route>
<route>
<driverId>noDriver</driverId>
<vehicleId>3_1</vehicleId>
<start>0.0</start>
<act type="service">
<serviceId>4 </serviceId>
<arrTime>109.98190391287031</arrTime>
<endTime>119.98190391287031</endTime>
</act>
<act type="service">
<serviceId>2 </serviceId>
<arrTime>119.98282618841856</arrTime>
<endTime>129.98282618841856</endTime>
</act>
<act type="service">
<serviceId>1 </serviceId>
<arrTime>129.98372097890456</arrTime>
<endTime>139.98372097890456</endTime>
</act>
<act type="service">
<serviceId>3 </serviceId>
<arrTime>139.9846432544528</arrTime>
<endTime>149.9846432544528</endTime>
</act>
<end>259.9668316441239</end>
</route>
</routes>
</solution>
</solutions>
基本上我在代码中向您展示的是仅从成本 = 505.9208295302417 的节点获取值,请不要考虑这部分代码,所以下一步是检索 driverid``, vehicleid and
act ,我知道缺少 for 循环但我不知道放在哪里!!请有人帮忙。我需要的期望输出就像每个 vehicleid
获取与其关联的列表行为值
java代码
public static void main(String[] args) {
try {
int totalVehicle;
totalVehicle = 2;
File fXmlFile = new File("C:/Users/HP/Desktop/solution.xml");
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(fXmlFile);
doc.getDocumentElement().normalize();
Double requiredCost = 505.9208295302417;
System.out.println("Root element :" + doc.getDocumentElement().getNodeName());
// NodeList nList = doc.getElementsByTagName("route");
System.out.println("----------------------------");
NodeList nodeList = doc.getElementsByTagName("solution");
for (int i = 0; i < nodeList.getLength(); i++) {
Node solutionNode = nodeList.item(i);
if (solutionNode.getNodeType() == Node.ELEMENT_NODE) {
Element solutionElement = (Element) solutionNode;
Node costNode = solutionElement.getElementsByTagName("cost").item(0);
Node route = solutionElement.getElementsByTagName("routes").item(0);
// if correct cost, proceed to parse further
Double costValue = Double.valueOf(costNode.getTextContent());
if (Double.compare(requiredCost, costValue) == 0) {
System.out.println("working");
// there you go, found the node with the cost 505.9208295302417
// now just parse all the node elements you need here
System.out.println("cost : "
+ solutionElement.getElementsByTagName("cost")
.item(0).getTextContent());
for (int h = 0; h < totalVehicle; h++) {
System.out.println("DriverId : "
+ solutionElement.getElementsByTagName("driverId")
.item(h).getTextContent().toString());
System.out.println("vehicleId : "
+ solutionElement.getElementsByTagName("vehicleId")
.item(h).getTextContent());
NodeList optionList = solutionElement.getElementsByTagName("act");
System.out.println(optionList.getLength());
for (int j = 0; j < optionList.getLength(); ++j)
{
for(int k =0;k<1;++k){
Element option = (Element) optionList.item(j);
String optionText = option.getTextContent();
//address.add(optionText.replaceAll("[^A-Za-z]"," "));
System.out.println("Citizen :"+optionText.replaceAll("[^A-Za-z]"," "));}
;
}
正如其他人所建议的那样,使用 xpath 会容易得多,但是如果您绝对需要遍历所有这些东西,请将问题分解成更小、更易于管理的部分。我想我会试一试,我有一个完整的、有效的解决方案来解决你的问题。
我们的想法是将 xml 分解为 Java 个对象并使用这些对象来完成您需要的工作。
public static void main(String... args) throws SAXException, IOException, ParserConfigurationException {
Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder()
.parse(new File("/home/william/Documents/test.xml"));
doc.getDocumentElement().normalize();
NodeList nodeList = doc.getElementsByTagName("solution");
for (int i = 0; i < nodeList.getLength(); i++) {
Node solutionNode = nodeList.item(i);
try {
System.out.println(Solution.newInstance(solutionNode).toString());
} catch (Exception e) {
// do something
e.printStackTrace();
}
}
}
在这里,您的原始文档的解析方式与您执行的方式相同,但解决方案是它自己的 class 您可以将逻辑放入:
public class Solution {
private final double cost;
private final Collection<Route> routes;
public static final Solution newInstance(Node solution) throws Exception {
return new Solution(solution);
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("solution:");
sb.append(System.lineSeparator());
sb.append("--------");
sb.append(System.lineSeparator());
sb.append("cost:");
sb.append(this.cost);
for (Route route : this.routes) {
sb.append(route.toString());
}
return sb.toString();
}
private Solution(Node solution) throws Exception {
if (solution.getNodeType() == Node.ELEMENT_NODE) {
Element solutionElement = (Element) solution;
this.cost = Double.valueOf(solutionElement.getElementsByTagName("cost").item(0).getTextContent());
this.routes = Routes.get(solutionElement.getElementsByTagName("routes").item(0));
} else {
// TODO something?
this.cost = 0D;
this.routes = Collections.emptyList();
}
}
}
请注意,在您的 main
方法中,您可以检查成本。我已经离开了所有 class 变量 getter 方法,如果您需要从对象外部读取它们,请添加您需要的方法。因此,例如在您的 Solution
class 中添加一个 getCost()
方法,然后在 main
方法中您可以适当地检查:if (solution.getCost() == requiredCost) {
...
在这里,根据您的要求,如果需要,您可以将 getter 添加到 class 成员中。我刚刚覆盖了 toString()
方法以打印您可以阅读的内容。
Routes
是一个实用程序 class,用于从 <routes>
节点的子节点中创建 Route
对象的集合。
public class Routes {
private final Collection<Route> items;
public static Collection<Route> get(Node routes) throws Exception {
return new Routes(routes).items;
}
private Routes() {
this.items = new ArrayList<>();
}
private Routes(Node routes) throws Exception {
this.items = new ArrayList<>();
NodeList routesList = routes.getChildNodes();
for (int i = 0; i < routesList.getLength(); i++) {
Node route = routesList.item(i);
if (Node.ELEMENT_NODE == route.getNodeType()) {
items.add(Route.newInstance(route));
} else {
// TODO something?
}
}
}
}
Acts
class 与 Routes
class 具有相似的逻辑(同样的事情,但对于行为):
public class Acts {
private Collection<Act> items;
public static Collection<Act> get(NodeList acts) throws Exception {
return new Acts(acts).items;
}
private Acts() {
this.items = new ArrayList<>();
}
private Acts(NodeList acts) throws Exception {
this.items = new ArrayList<>();
for (int i = 0; i < acts.getLength(); i++) {
Node act = acts.item(i);
if (Node.ELEMENT_NODE == act.getNodeType()) {
this.items.add(Act.newInstance(act));
} else {
// TODO something?
}
}
}
}
最后,每个人 Act
:
public class Act {
private final String service;
private final double arrTime;
private final double endTime;
public static Act newInstance(Node act) throws Exception {
return new Act(act);
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("Act");
sb.append(System.lineSeparator());
sb.append("arr time");
sb.append(System.lineSeparator());
sb.append(this.arrTime);
sb.append(System.lineSeparator());
sb.append("end time:");
sb.append(System.lineSeparator());
sb.append(this.endTime);
sb.append(System.lineSeparator());
sb.append("service:");
sb.append(System.lineSeparator());
sb.append(this.service);
return sb.toString();
}
private Act(Node act) throws Exception {
Element actElement = (Element) act;
this.service = actElement.getAttribute("service");
this.arrTime = Double.valueOf(actElement.getElementsByTagName("arrTime").item(0).getTextContent());
this.endTime = Double.valueOf(actElement.getElementsByTagName("endTime").item(0).getTextContent());
}
}