SAX 解析和父/子关系

SAX parsing and parent / child relations

所以我面临这个问题,我需要解析一个 XML 文件来填充域对象。听起来很简单,但是,XML 文件中的元素可以有未知数量的子元素,因此域对象可以有一个实例变量到 class 的另一个对象,该对象可以有一个变量到相同 class 的实例变量,依此类推。举个例子,这是为 XML 文件提供的示例:

<categories>
    <category id="1">
        <name>XML</name>
        <category id="2">
            <name>XPath</name>
        </category>
        <category id="3">
            <name>XML Schema</name>
        </category>
        <category id="4">
            <name>XSLT</name>
        </category>
        <category id="5">
            <name>XSL-FO</name>
        </category>
        <category id="6">
            <name>XQuery</name>
        </category>
    </category>
    <category id="7">
        <name>Java</name>
        <category id="100">
            <name>SDK</name>
            <category id="8">
                <name>Collections</name>
            </category>
            <category id="9">
                <name>NIO</name>
            </category>
            <category id="10">
                <name>Concurrency</name>
            </category>
        </category>
        <category id="1000">
            <name>EE</name>
            <category id="11">
                <name>EJB</name>
            </category>
            <category id="12">
                <name>Web</name>
            </category>
            <category id="13">
                <name>Webservices</name>
            </category>
        </category>
        <category id="0">
            <name>Examen boeken</name>
        </category>
    </category>
</categories>

我已经使用 DOM 解析器完成了此操作,但为了我的研究,我还需要使用 SAX 解析器来完成此操作。我陷入了这样的境地,我需要告诉我哪个元素有哪些子元素,哪个元素有哪些父元素。

截至目前,我设法在包含其 ID 和名称的地图中获取所有类别条目。

代码如下所示:

public static void main(String[] args) throws SAXException, IOException,
        ParserConfigurationException {
    Bookshelf mijnBookshelf = new Bookshelf("boekenfestijn");
    Map<Integer, Category> categories = new HashMap<Integer, Category>();
    // TODO inlezen
    try {

        SAXParserFactory factory = SAXParserFactory.newInstance();
        SAXParser saxParser = factory.newSAXParser();

        DefaultHandler handler = new DefaultHandler() {

            String reading = null;

            boolean inCategory = false;
            boolean inName = false;

            int categoryId;

            Category currentCategory;


            public void startElement(String uri, String localName,
                    String qName, Attributes attributes)
                    throws SAXException {

                if(qName.equalsIgnoreCase("CATEGORY") && attributes.getValue("id") != null){
                    inCategory = true;
                    categoryId = Integer.parseInt(attributes.getValue("id"));
                    System.out.println("START HANDLING ID -> " + attributes.getValue("id"));

                }
                if(qName.equalsIgnoreCase("NAME")){
                    inName = true;
                }


            }

            public void endElement(String uri, String localName,
                    String qName) throws SAXException {


                if(inCategory){
                    inCategory = false;
                    System.out.println("CATEGORY ID : " + categoryId + " NAME : " + reading);
                    currentCategory = new Category(categoryId, reading);
                    currentCategory.setBookshelf(mijnBookshelf);
                    categories.put(categoryId, currentCategory);
                    System.out.println("END HANDLING");
                }

                if(inName){
                    inName = false;
                }



            }













            public void characters(char ch[], int start, int length)
                    throws SAXException {
                reading = new String(ch, start, length);


            }

        };

        saxParser.parse("bookshelf.xml", handler);

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

    for (Integer i : categories.keySet()) {
        System.out.println("ID: " + categories.get(i).getId() + "->"
                + categories.get(i).getName());
    }

而对于 "category" class

public class Category {

private Integer id;
private String name;
private Category parent;
private List<Category> children = new ArrayList<Category>();
private Bookshelf bookshelf;

public Category(){

}

public Category(Integer id, String name) {
    super();
    this.id = id;
    this.name = name;
}

public Integer getId() {
    return id;
}

public void setId(Integer id) {
    this.id = id;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public Category getParent() {
    return parent;
}

public void setParent(Category parent){
    this.parent = parent;
}

public List<Category> getChildren() {
    return children;
}

public String toString() {
    String s = bookshelf.getName() + "/";
    if (parent != null) {
        s = parent.toString();
    }
    s += name + "/";
    return s;
}

public Bookshelf getBookshelf() {
    return bookshelf;
}

public void setBookshelf(Bookshelf bookshelf) {
    this.bookshelf = bookshelf;
}

这就是我卡住的地方?我怎样才能继续定义父子关系?我怎么知道在我的处理程序中的任何时候哪个元素有哪个元素作为子元素/父元素?

如有任何帮助,我们将不胜感激!

TLDR:如何在使用 sax 解析器填充域对象时定义父/子关系?

在 SAX 中,您无法直接知道哪个元素是另一个元素的父元素。处理此信息的常用方法是管理 LIFO 堆栈(例如 java.util.Stack)。您在 startElement() 方法上推送元素,并在 endElement().

方法上弹出它

不幸的是,由于 startElement().

,您 "met" 之前无法预测子元素