成功将元素解析到列表后,SAX解析器endDocument中的空列表

时间:2014-10-10 08:26:12

标签: java android sax nutiteq

我尝试解析包含地理节点的XML以及使用SAX解析器连接节点的方法。我将解析后的节点存储在ArrayMap<Long, MapPos>中,并将方式存储在ArrayList<ArrayList<MapPos>>中。在解析方法时,我创建了ArrayList<MapPos>个引用的节点,并将其添加到ArrayList方式。

调试应用程序后,我看到startElement()endElement()成功地为ArrayList添加了方法,但在endDocument()方法中方式 ArrayList只包含一堆空的ArrayList

这是java类:

public class ParkingDataExtractor {
    private static List<ArrayList<MapPos>> roads = new ArrayList<ArrayList<MapPos>>();

    public static List<ArrayList<MapPos>> getWaysFromXML()
            throws ParserConfigurationException, SAXException, IOException{

        SAXParser saxParser = SAXParserFactory.newInstance().newSAXParser();
        DefaultHandler handler = new DefaultHandler() {
            ArrayMap<Long, MapPos> nodes = new ArrayMap<Long, MapPos>();
            ArrayList<MapPos> nodeBuffer = new ArrayList<MapPos>();
            List<ArrayList<MapPos>> ways = new ArrayList<ArrayList<MapPos>>();
            // private int i; // for debug purposes

            @Override
            public void startElement(String uri, String localName,
                    String qName, Attributes attributes)
                    throws SAXException {
                if (qName.equalsIgnoreCase("node")) {
                    Long id = Long.parseLong(attributes.getValue("id"));
                    Float lat = Float
                            .parseFloat(attributes.getValue("lat"));
                    Float lon = Float
                            .parseFloat(attributes.getValue("lon"));
                    nodes.put(id, new MapPos(lat, lon));
                } else if (qName.equalsIgnoreCase("nd")) {
                    Long ref = Long.parseLong(attributes.getValue("ref"));
                    nodeBuffer.add(nodes.get(ref));
                }
            }

            @Override
            public void endElement(String uri, String localName,
                    String qName) throws SAXException {
                if (qName.equalsIgnoreCase("way")) {
                    ways.add(nodeBuffer);
                    // i++;
                    // if(i==1590) // last element
                    //     ArrayList<MapPos> test = ways.get(i-1); // test = [MapPos [x=..., y=..., z=0.0], MapPos [x=..., y=..., z=0.0],...]
                    nodeBuffer.clear();
                }
            }

            @Override
            public void endDocument() throws SAXException {
                // ArrayList<MapPos> test = ways.get(i-1); // test = []
                roads = ways;
            }
        };

        saxParser.parse("file://" + Environment.getExternalStorageDirectory() 
                + "/roadmap.xml", handler);
        return roads;
    }
}

2 个答案:

答案 0 :(得分:2)

当您致电nodeBuffer.clear()时,您清空了刚刚传递给方法的列表。你基本上反复使用相同的nodeBuffer对象,并在ways列表中填入大量对同一对象的引用 - 每次都清空。

您应该这样做的方法是使用ArrayList创建一个新的new对象,并且每次都将其分配给nodeBuffer。然后,您将拥有单独的对象,每个对象都包含在最新一轮中解析的节点列表。

答案 1 :(得分:0)

请尝试这种方式,希望这有助于您解决问题。

public class ParkingDataExtractor {
    private static List<ArrayList<MapPos>> roads = new ArrayList<ArrayList<MapPos>>();

    public static List<ArrayList<MapPos>> getWaysFromXML() throws ParserConfigurationException, SAXException, IOException{
        SAXParser saxParser = SAXParserFactory.newInstance().newSAXParser();

        DefaultHandler handler = new DefaultHandler() {
            ArrayMap<Long, MapPos> nodes = new ArrayMap<Long, MapPos>();
            ArrayList<MapPos> nodeBuffer;
            List<ArrayList<MapPos>> ways = new ArrayList<ArrayList<MapPos>>();

            @Override
            public void startElement(String uri, String localName,String qName, Attributes attributes) throws SAXException {
                if (qName.equalsIgnoreCase("node")) {
                    Long id = Long.parseLong(attributes.getValue("id"));
                    Float lat = Float.parseFloat(attributes.getValue("lat"));
                    Float lon = Float.parseFloat(attributes.getValue("lon"));
                    nodes.put(id, new MapPos(lat, lon));
                } else if (qName.equalsIgnoreCase("nd")) {
                    Long ref = Long.parseLong(attributes.getValue("ref"));
                    nodeBuffer = new ArrayList<MapPos>();
                    nodeBuffer.add(nodes.get(ref));
                }
            }

            @Override
            public void endElement(String uri, String localName,String qName) throws SAXException {
                if (qName.equalsIgnoreCase("way")) {
                    ways.add(nodeBuffer);
                }
            }

            @Override
            public void endDocument() throws SAXException {
                roads = ways;
            }
        };

        saxParser.parse("file://" + Environment.getExternalStorageDirectory() + "/roadmap.xml", handler);
        return roads;
    }
}