2013-03-07 73 views
1

我在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是完成课程?

+0

你需要做一个两遍解析;在课程中存储'String' prereq,然后创建一个'Map '并在课程'resolvePrereq(final Map lookupMap)'上有某种方法,然后循环并调用。 – 2013-03-07 20:39:14

+0

如果您为“课程”添加源代码,那么对于解决方案而言,更容易具体。 – 2013-03-07 20:41:43

+0

这就是我想要做的,但我真的不知道如何。 – DarkLordAllie 2013-03-07 20:48:51

回答

1

您需要维护一个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并使用它来获得您的课程。它将处理确保你总是参考同一个。