gpt4 book ai didi

java - 在 Java 中读取多级 XML 文件

转载 作者:数据小太阳 更新时间:2023-10-29 02:16:33 25 4
gpt4 key购买 nike

直到最近,我的 XML 文件的标签结构还相当简单。但是现在我多了一层带有标签的标签,解析 XML 变得更加复杂。

这是我的新 XML 文件的示例(我更改了标签名称以使其更易于理解):

<SchoolRoster>
<Student>
<name>John</name>
<age>14</age>
<course>
<math>A</math>
<english>B</english>
</course>
<course>
<government>A+</government>
</course>
</Student>
<Student>
<name>Tom</name>
<age>13</age>
<course>
<gym>A</gym>
<geography>incomplete</geography>
</course>
</Student>
</SchoolRoster>

上面的 XML 的重要特征是我可以有多个“类(class)”属性,并且在其中我可以有任意命名的标签作为它们的 child 。可以有任意数量的这些 child ,我想将其读入“名称”、“值”的 HashMap。

public static TreeMap getAllSchoolRosterInformation(String fileName) {
TreeMap SchoolRoster = new TreeMap();

try {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
File file = new File(fileName);
if (file.exists()) {
Document doc = db.parse(file);
Element docEle = doc.getDocumentElement();
NodeList studentList = docEle.getElementsByTagName("Student");

if (studentList != null && studentList.getLength() > 0) {
for (int i = 0; i < studentList.getLength(); i++) {

Student aStudent = new Student();
Node node = studentList.item(i);

if (node.getNodeType() == Node.ELEMENT_NODE) {
Element e = (Element) node;
NodeList nodeList = e.getElementsByTagName("name");
aStudent.setName(nodeList.item(0).getChildNodes().item(0).getNodeValue());

nodeList = e.getElementsByTagName("age");
aStudent.setAge(Integer.parseInt(nodeList.item(0).getChildNodes().item(0).getNodeValue()));

nodeList = e.getElementsByTagName("course");
if (nodeList != null && nodeList.getLength() > 0) {
Course[] courses = new Course[nodeList.getLength()];
for (int j = 0; j < nodeList.getLength(); j++) {

Course singleCourse = new Course();
HashMap classGrades = new HashMap();
NodeList CourseNodeList = nodeList.item(j).getChildNodes();

for (int k = 0; k < CourseNodeList.getLength(); k++) {
if (CourseNodeList.item(k).getNodeType() == Node.ELEMENT_NODE && CourseNodeList != null) {
classGrades.put(CourseNodeList.item(k).getNodeName(), CourseNodeList.item(k).getNodeValue());
}
}
singleCourse.setRewards(classGrades);
Courses[j] = singleCourse;
}
aStudent.setCourses(Courses);
}
}
SchoolRoster.put(aStudent.getName(), aStudent);
}
}
} else {
System.exit(1);
}
} catch (Exception e) {
System.out.println(e);
}
return SchoolRoster;
}

我遇到的问题是,不是让学生在“数学”中获得“A”,而是在“数学”中获得空值。 (如果这篇文章太长,我可以尝试找到一些缩短它的方法。)

最佳答案

如果这是我的项目,我会避免尝试手动剖析 HTML 中的数据,而是让 Java 使用 JAXB 为我做这件事。我越使用这个工具,就越喜欢它。我敦促您考虑尝试这样做,因为如果您这样做,将 XML 更改为 Java 对象所需要做的就是在 Java 类中添加适当的注释,然后解码 XML。使用的代码会简单得多,因此出错的可能性也会大大降低。

例如,以下代码非常容易且干净地将信息编码到 XML 中:

import java.util.ArrayList;
import java.util.List;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;

@XmlRootElement
public class SchoolRoster {
@XmlElement(name = "student")
private List<Student> students = new ArrayList<Student>();

public SchoolRoster() {
}

public List<Student> getStudents() {
return students;
}

public void addStudent(Student student) {
students.add(student);
}

public static void main(String[] args) {
Student john = new Student("John", 14);
john.addCourse(new Course("math", "A"));
john.addCourse(new Course("english", "B"));

Student tom = new Student("Tom", 13);
tom.addCourse(new Course("gym", "A"));
tom.addCourse(new Course("geography", "incomplete"));

SchoolRoster roster = new SchoolRoster();
roster.addStudent(tom);
roster.addStudent(john);

try {
JAXBContext context = JAXBContext.newInstance(SchoolRoster.class);
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

String pathname = "MySchoolRoster.xml";
File rosterFile = new File(pathname );
marshaller.marshal(roster, rosterFile);
marshaller.marshal(roster, System.out);

} catch (JAXBException e) {
e.printStackTrace();
}
}
}

@XmlRootElement
@XmlType(propOrder = { "name", "age", "courses" })
class Student {
// TODO: completion left as an exercise for the original poster
}

@XmlRootElement
@XmlType(propOrder = { "name", "grade" })
class Course {
// TODO: completion left as an exercise for the original poster
}

这导致了以下 XML:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<schoolRoster>
<student>
<name>Tom</name>
<age>13</age>
<courses>
<course>
<name>gym</name>
<grade>A</grade>
</course>
<course>
<name>geography</name>
<grade>incomplete</grade>
</course>
</courses>
</student>
<student>
<name>John</name>
<age>14</age>
<courses>
<course>
<name>math</name>
<grade>A</grade>
</course>
<course>
<name>english</name>
<grade>B</grade>
</course>
</courses>
</student>
</schoolRoster>

将其解码到充满数据的 SchoolRoster 类中只需几行代码。

private static void unmarshallTest() {
try {
JAXBContext context = JAXBContext.newInstance(SchoolRoster.class);
Unmarshaller unmarshaller = context.createUnmarshaller();

String pathname = "MySchoolRoster.xml"; // whatever the file name should be
File rosterFile = new File(pathname );
SchoolRoster roster = (SchoolRoster) unmarshaller.unmarshal(rosterFile);
System.out.println(roster);
} catch (JAXBException e) {
e.printStackTrace();
}
}

在我的类中添加了 toString() 方法之后,结果是:

SchoolRoster 
[students=
[Student [name=Tom, age=13, courses=[Course [name=gym, grade=A], Course [name=geography, grade=incomplete]]],
Student [name=John, age=14, courses=[Course [name=math, grade=A], Course [name=english, grade=B]]]]]

关于java - 在 Java 中读取多级 XML 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11268762/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com