简体   繁体   English

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

[英]Empty list in SAX parser endDocument after successfully parsing elements to the list

I'm trying to parse an XML containing geographic nodes and ways connecting the nodes using SAX parser. 我正在尝试解析包含地理节点和使用SAX解析器连接节点的方式的XML。 I store the parsed nodes in an ArrayMap<Long, MapPos> and the ways in an ArrayList<ArrayList<MapPos>> . 我将解析的节点存储在ArrayMap<Long, MapPos> ,并将方式存储在ArrayList<ArrayList<MapPos>> When parsing a way, I create an ArrayList<MapPos> of the referenced nodes and add this to the ArrayList of ways. 解析方式时,我创建了引用节点的ArrayList<MapPos>并将其添加到方式的ArrayList中。

After debugging the application, I see that startElement() and endElement() successfully adds the ways to the ArrayList , but in the endDocument() method the ways ArrayList contains nothing but a bunch of empty ArrayList . 在调试应用程序之后,我看到startElement()endElement()成功地将方法添加到ArrayList ,但是在endDocument()方法中, ArrayList方法只包含一堆空ArrayList

Here is the java class: 这是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;
    }
}

When you call nodeBuffer.clear() you empty the list that you have just passed on to ways. 当您调用nodeBuffer.clear()您将清空刚刚传递给方法的列表。 You basically use the same nodeBuffer object over and over, and fill the ways list with a lot of references to the same object - which you empty each time. 基本上,您nodeBuffer使用相同的nodeBuffer对象,并在ways列表中填充对同一对象的大量引用-您每次都将其清空。

The way you should do it is create a new ArrayList object using new and assign it to nodeBuffer every time. 您应该这样做的方法是使用new创建一个新的ArrayList对象,并每次将其分配给nodeBuffer You will then have separate objects, each containing the list of nodes parsed in the latest round. 然后,您将拥有单独的对象,每个对象都包含最近一轮中解析的节点列表。

Try this way,hope this will help you to solve your problem. 尝试这种方式,希望这将帮助您解决问题。

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;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM