我尝试解析包含地理节点的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;
}
}
答案 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;
}
}