使用SAX解析具有未知递归量的XML结构

我必须使用SAX解析器在JAVA中解析XML结构。

问题是结构是递归的,具有未指定的递归计数。 这仍然不是什么大问题,最重要的是我无法利用XML命名空间function,并且每个递归级别的标签都是相同的。

这是结构的一个例子。

                  

正如您所看到的那样,有一个递归,更好的是一个未定义的递归数。 现在我的问题是如何为每次递归提取所有数据并将其保存在HashMap中。

我可以为Tags的出现定义一个ContentHandler并让它在HashMap提取内容并将其放回主内容处理程序中定义的 HashMap中,但我不确定这样做会很热。

如何在不使用命名空间的情况下提取和保存递归XML结构的内容?

查看这组关于使用SAX的Javaworld文章 。 它演示了使用SAX解析递归XML结构的简单方法。 它创建一个状态机,为每个元素显示它可以包含哪些元素。 当您的contentHandler遍历xml时,它会保持一个堆栈,显示它当前所在的元素。

如果要通过SAX递归解析XML,则必须使用Stack并检查XML结构中的深度。 对于我这种格式的XML结构(最大深度为3):

      ...  ...  ...   

我使用了这个Java伪代码,它在我的Android应用程序中运行得非常好(已知深度)。 如果你不知道递归的数量并且不知道深度,你可以只编辑我的代码并代替3个ArrayList对象(和3个Category对象),你可以使用一个动态集合(例如ArrayList> )并使用索引将ArrayList放入ArrayList> ,它提供了getDepth()方法。

 public class CategoriesResponse extends Response { private Stack mTagStack = new Stack(); private ArrayList mCategories1; private ArrayList mCategories2; private ArrayList mCategories3; Category mCategory1; Category mCategory2; Category mCategory3; private int mCurrentDepth = 0; public ArrayList getCategories() { return mCategories1; } public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { super.startElement(uri, localName, qName, attributes); ... if(localName.equals("Category")) { // push element into the stack mTagStack.push(localName); // get data int id = Integer.parseInt(attributes.getValue("id")); String name = attributes.getValue("name"); int numSubcategories = Integer.parseInt(attributes.getValue("numSubcategories")); // create new Category if(getDepth()==1) { mCategory1 = new Category(id, name); mCategory1.setSubcategoriesSize(numSubcategories); mCategory1.setSubcategories(null); if(mCurrentDepth(); // deeping down so create new list } else if(getDepth()==2) { mCategory2 = new Category(id, name); mCategory2.setSubcategoriesSize(numSubcategories); mCategory2.setSubcategories(null); if(mCurrentDepth(); // deeping down so create new list } else if(getDepth()==3) { mCategory3 = new Category(id, name); mCategory3.setSubcategoriesSize(numSubcategories); mCategory3.setSubcategories(null); if(mCurrentDepth(); // deeping down so create new list } // debug output if(mCurrentDepthgetDepth()) Log.d("SAX_TEST", getPath() + " | " + getDepth() + " | DEEPING UP"); else if(mCurrentDepth==getDepth()) Log.d("SAX_TEST", getPath() + " | " + getDepth() + " | STAYING"); // set current depth mCurrentDepth = getDepth(); return; } } public void characters(char[] ch, int start, int length) throws SAXException { super.characters(ch, start, length); ... } public void endElement(String uri, String localName, String qName) throws SAXException { super.endElement(uri, localName, qName); ... if(localName.equals("Category")) { // debug output Log.d("SAX_TEST", "END OF THE ELEMENT IN DEPTH " + getDepth() + " | " + mCurrentDepth); // deeping up so set sublist for current category if(getDepth()!=mCurrentDepth) { if(getDepth()==2) mCategory2.setSubcategories(mCategories3); if(getDepth()==1) mCategory1.setSubcategories(mCategories2); } // add current category to list if(getDepth()==1) { mCategories1.add(mCategory1); } else if(getDepth()==2) { mCategories2.add(mCategory2); } else if(getDepth()==3) { mCategories3.add(mCategory3); } // pop element from stack mTagStack.pop(); return; } } // debug output - write current path private String getPath() { String buffer = ""; Enumeration e = mTagStack.elements(); while (e.hasMoreElements()) { buffer = buffer + "/" + (String) e.nextElement(); } return buffer; } // get current depth of stack private int getDepth() { return mTagStack.size(); } }