将XML文件解析为链接的java对象
问题描述:
我在XML文件上使用SAX解析器来创建引用对象的对象。将XML文件解析为链接的java对象
<?xml version="1.0"?>
<xml encoding="UTF-8" version="1.0">
<course number="CSC212">
<textbook name="BookFor212"/>
</course>
<course number="CSC241">
<prereq number="CSC212"/>
<textbook name="BookFor241"/>
<textbook name="AnotherBookFor241"/>
</course>
<course number="CSC455">
<prereq number="CSC241"/>
<prereq number="CSC365"/>
<textbook name="BookFor455"/>
</course>
<course number="CSC365">
<prereq number="CSC241"/>
<textbook name="BookFor365"/>
<textbook name="AnotherBookFor365"/>
<textbook name="YetAnotherBookFor365"/>
</course>
</xml>
所以我创建一个进程和教科书和prereqs添加到过程内的各个阵列和完成I的过程添加到阵列。解析后,用户会被提示输入课程编号,程序会吐出信息,包括前提条件以及它们所包含的所有内容,以及他们的教科书和前提条件。
public class Course {
private String number;
private Course[] prereqs = new Course[5];
private int pCounter = 0;
private Textbook[] books = new Textbook[5];
private int tCounter = 0;
public Course(String n) {
number = n;
}
public String getNumber() {
return number;
}
public void addPrereq(Course prereq) {
prereqs[pCounter++] = prereq;
}
public void addTextbook(Textbook book) {
books[tCounter++] = book;
}
public String toString() {
String retVal = "Course: " + number + (tCounter == 0 ? ", No books." : ", textbooks: ");
for (int i = 0; i < tCounter; i++)
retVal += books[i].toString() + " ";
retVal += "\n" + (pCounter == 0 ? "No prerequisites.\n" : "Prerequisites:\n");
for (int i = 0; i < pCounter; i++)
retVal += prereqs[i].toString();
return retVal + "End of course " + number + ".\n";
}
}
的问题是添加prereqs我通过已经建立的课程阵列看,如果它的存在,使用它,并创建一个新的,如果它不是时。所以如果它不在那里,我会添加一个课程,除了它的编号之外,没有任何信息。所以我最终选择的课程CSC455有一个prereq CSC365,但没有列出任何教科书或先决条件。我怎样才能做到这一点,以便prereqs是完成课程?
答
您需要维护一个Map
来查找您的课程。每当您遇到新的Course
或参考时,请检查地图,然后将新的Course
s放入地图。通过这种方式,您可以从请求中创建Course
,然后再添加信息。
我建议你Course
因为这样使用List
S或Set
s就意味着你不会得到一个ArrayOutOfBounds
当你有超过5本教科书。
public class Course {
private String number;
private List<Course> prereqs = new LinkedList<Course>();
private List<Textbook> books = new LinkedList<Textbook>();
public Course(String n) {
number = n;
}
public String getNumber() {
return number;
}
public void addPrereq(Course prereq) {
prereqs.add(prereq);
}
public void addTextbook(Textbook book) {
books.add(book);
}
public String toString() {
String retVal = "Course: " + number + (books.isEmpty() ? ", No books." : ", textbooks: ");
for (final Textbook book : books) {
retVal += book.toString() + " ";
}
retVal += "\n" + (prereqs.isEmpty() ? "No prerequisites.\n" : "Prerequisites:\n");
for (final Course course : prereqs) {
retVal += course.toString();
}
return retVal + "End of course " + number + ".\n";
}
}
现在你需要存储Map<String, Course>
,并添加使用,而不是修建新课程getCourse()
方法 - 这是一个工厂模式:
private class CourseFactory {
private final Map<String, Course> courseMap;
public CourseFactory(final Map<String, Course> courseMap) {
this.courseMap = courseMap;
}
public Course getCourse(final String name) {
Course course = courseMap.get(name);
if(course == null) {
course = new Course(name);
courseMap.put(name, course);
}
return course;
}
}
所以,现在你的解析器的顶部,你创建一个CourseFactory
并使用它来获得您的课程。它将处理确保你总是参考同一个。
你需要做一个两遍解析;在课程中存储'String' prereq,然后创建一个'Map'并在课程'resolvePrereq(final Map lookupMap)'上有某种方法,然后循环并调用。 –
2013-03-07 20:39:14
如果您为“课程”添加源代码,那么对于解决方案而言,更容易具体。 – 2013-03-07 20:41:43
这就是我想要做的,但我真的不知道如何。 – DarkLordAllie 2013-03-07 20:48:51