1

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

调试应用程序后,我看到startElement()endElement()成功将方法添加.ArrayListendDocument() ArrayListArrayList

这是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;
    }
}
4

2 回答 2

2

当你打电话给nodeBuffer.clear()你时,你会清空你刚刚传递给方式的列表。nodeBuffer您基本上一遍又一遍地使用同一个对象,并用对同一个对象ways的大量引用填充列表 - 您每次都清空这些引用。

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

于 2014-10-10T08:49:41.770 回答
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;
    }
}
于 2014-10-10T08:37:04.330 回答