我正在尝试自己构建一个XML解析器(实际上它是GPX解析器)。
在编写代码时,有些问题突然出现了。
我的一些代码如下。
public class GPXFileParser extends AbstractFileParser {
private volatile File gpxFile;
boolean isCoreDate = false;
private static final String XML_OPENER = "<";
private static final String XML_CLOSER = "</";
private static final String XML_END = ">";
private static final String ATTR = "=";
private static final String SPACE = " ";
Map<String, Object> mapData;
public GPXFileParser() {
mapData = new HashMap<String, Object>();
}
public GPXFileParser(String filePath) {
gpxFile = new File(filePath);
if(gpxFile.exists() && gpxFile.isFile()){
if(!gpxFile.canExecute()) gpxFile.setExecutable(true);
}
mapData = new HashMap<String, Object>();
}
private String getXmlKey(String line) {
String temp = "";
if(line.contains(XML_OPENER)) {
temp = line.substring(1, line.indexOf(XML_END));
}
return temp;
}
private String getXmlVal(String key, String line) {
String temp = "";
if(line.contains(XML_CLOSER)){
line = line.substring(line.indexOf(XML_END) + 1);
temp = line.substring(0, line.indexOf(XML_CLOSER));
}
return temp;
}
private List<Map<String, Object>> getAttributeIfNotNull(String key) {
List<Map<String, Object>> ret = new ArrayList<Map<String,Object>>();
String[] attributes = key.split(SPACE);
if(attributes.length < 2) return ret;
for(int i = 0; i < attributes.length; i++) {
Map<String, Object> single = new HashMap<String, Object>();
String singleAttribute = attributes[i];
if(!singleAttribute.contains(ATTR)) continue;
String attrKey = singleAttribute.split(ATTR)[0];
String attrVal = StringUtils.removeColons(singleAttribute.split(ATTR)[1]);
single.put(attrKey, attrVal);
ret.add(single);
}
return ret;
}
@Override
public Map<String, Object> parse(File param) throws Exception {
if(gpxFile == null) gpxFile = new File(param.getAbsolutePath());
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(gpxFile)));
String singleLine = "";
boolean hasSub = false;
int dept = 0;
while((singleLine =br.readLine()) != null){
HashMap<String, Object> single = null;
singleLine = singleLine.trim();
if(singleLine.contains("<trk>")){isCoreDate = true;
}else if(singleLine.contains("</trk>")){isCoreDate = false;}
if(isCoreDate){
if(singleLine.startsWith(XML_CLOSER)) continue;
int openCnt = StringUtils.getSubStringCnt(singleLine, XML_OPENER);
int closeCnt = StringUtils.getSubStringCnt(singleLine, XML_CLOSER);
if(openCnt == closeCnt) hasSub = false;
else {
if(openCnt > closeCnt){
hasSub = true;
}
}
single = new HashMap<String, Object>();
String key = getXmlKey(singleLine);
System.out.println("key >> " + key);
List<Map<String, Object>> attrList = getAttributeIfNotNull(key);
if(attrList.isEmpty()){
String val = getXmlVal(key, singleLine);
System.out.println("val >> " + val);
single.put(key, val);
}else{
key = key.split(SPACE)[0];
single.put(key, attrList);
}
if(!single.isEmpty()) mapData.putAll(single);
}
}
br.close();
return mapData;
}
};
我需要一些参考建议,它们不使用第三方库或架构师原则。
我期望的是树型地图,但我的代码只返回1个深度图。
{trkseg=, extensions=, gpxtpx:atemp=18.0, name=awesome riding, trkpt=[{lon=126.29451882094145}, {lat=33.443800024688244}], time=2015-05-01T21:55:10.000Z, gpxtpx:TrackPointExtension=, gpxtpx:cad=49, trk=}
感谢您查看我的代码和答案:D
P.S。我原来的数据是......
<?xml version="1.0" encoding="UTF-8"?>
<gpx version="1.1" creator="Garmin Connect"
xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd http://www.garmin.com/xmlschemas/GpxExtensions/v3 http://www.garmin.com/xmlschemas/GpxExtensionsv3.xsd http://www.garmin.com/xmlschemas/TrackPointExtension/v1 http://www.garmin.com/xmlschemas/TrackPointExtensionv1.xsd"
xmlns="http://www.topografix.com/GPX/1/1"
xmlns:gpxtpx="http://www.garmin.com/xmlschemas/TrackPointExtension/v1"
xmlns:gpxx="http://www.garmin.com/xmlschemas/GpxExtensions/v3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<metadata>
<link href="connect.garmin.com">
<text>Garmin Connect</text>
</link>
<time>2015-05-01T21:51:42.000Z</time>
</metadata>
<trk>
<name>Awesome riding!</name>
<trkseg>
<trkpt lon="126.28584556281567" lat="33.4417990129441">
<time>2015-05-01T21:51:42.000Z</time>
</trkpt>
<trkpt lon="126.28585444763303" lat="33.441797671839595">
<time>2015-05-01T21:51:43.000Z</time>
</trkpt>
<trkpt lon="126.28589048981667" lat="33.441788451746106">
<time>2015-05-01T21:51:44.000Z</time>
</trkpt>
<trkpt lon="126.28591739572585" lat="33.44177604652941">
<time>2015-05-01T21:51:45.000Z</time>
</trkpt>
<trkpt lon="126.28594572655857" lat="33.44176380895078">
<time>2015-05-01T21:51:46.000Z</time>
<extensions>
<gpxtpx:TrackPointExtension>
<gpxtpx:atemp>20.0</gpxtpx:atemp>
</gpxtpx:TrackPointExtension>
</extensions>
</trkpt>
<trkpt lon="126.28597606904805" lat="33.44175492413342">
<time>2015-05-01T21:51:47.000Z</time>
<extensions>
<gpxtpx:TrackPointExtension>
<gpxtpx:atemp>20.0</gpxtpx:atemp>
</gpxtpx:TrackPointExtension>
</extensions>
</trkpt>
<trkpt lon="126.28600666299462" lat="33.441743860021234">
<time>2015-05-01T21:51:48.000Z</time>
<extensions>
<gpxtpx:TrackPointExtension>
<gpxtpx:atemp>20.0</gpxtpx:atemp>
<gpxtpx:cad>27</gpxtpx:cad>
</gpxtpx:TrackPointExtension>
</extensions>
</trkpt>
<trkpt lon="126.28603314980865" lat="33.441728772595525">
<time>2015-05-01T21:51:49.000Z</time>
<extensions>
<gpxtpx:TrackPointExtension>
<gpxtpx:atemp>20.0</gpxtpx:atemp>
<gpxtpx:cad>0</gpxtpx:cad>
</gpxtpx:TrackPointExtension>
</extensions>
</trkpt>
<trkpt lon="126.28606181591749" lat="33.44171678647399">
<time>2015-05-01T21:51:50.000Z</time>
<extensions>
<gpxtpx:TrackPointExtension>
<gpxtpx:atemp>20.0</gpxtpx:atemp>
<gpxtpx:cad>0</gpxtpx:cad>
</gpxtpx:TrackPointExtension>
</extensions>
</trkpt>
<trkpt lon="126.28608050756156" lat="33.4416954126209">
<time>2015-05-01T21:51:51.000Z</time>
<extensions>
<gpxtpx:TrackPointExtension>
<gpxtpx:atemp>20.0</gpxtpx:atemp>
<gpxtpx:cad>0</gpxtpx:cad>
</gpxtpx:TrackPointExtension>
</extensions>
</trkpt>
<trkpt lon="126.2860903982073" lat="33.441674122586846">
<time>2015-05-01T21:51:52.000Z</time>
<extensions>
<gpxtpx:TrackPointExtension>
<gpxtpx:atemp>20.0</gpxtpx:atemp>
<gpxtpx:cad>0</gpxtpx:cad>
</gpxtpx:TrackPointExtension>
</extensions>
</trkpt>
<trkpt lon="126.28609601408243" lat="33.44165383838117">
<time>2015-05-01T21:51:53.000Z</time>
<extensions>
<gpxtpx:TrackPointExtension>
<gpxtpx:atemp>20.0</gpxtpx:atemp>
<gpxtpx:cad>0</gpxtpx:cad>
</gpxtpx:TrackPointExtension>
</extensions>
</trkpt>
<trkpt lon="126.2860840279609" lat="33.441627100110054">
<time>2015-05-01T21:51:54.000Z</time>
<extensions>
<gpxtpx:TrackPointExtension>
<gpxtpx:atemp>20.0</gpxtpx:atemp>
<gpxtpx:cad>0</gpxtpx:cad>
</gpxtpx:TrackPointExtension>
</extensions>
</trkpt>
<trkpt lon="126.2860647495836" lat="33.44160404987633">
<time>2015-05-01T21:51:55.000Z</time>
<extensions>
<gpxtpx:TrackPointExtension>
<gpxtpx:atemp>20.0</gpxtpx:atemp>
<gpxtpx:cad>12</gpxtpx:cad>
</gpxtpx:TrackPointExtension>
</extensions>
</trkpt>
<trkpt lon="126.28604924306273" lat="33.44158200547099">
<time>2015-05-01T21:51:56.000Z</time>
<extensions>
<gpxtpx:TrackPointExtension>
<gpxtpx:atemp>20.0</gpxtpx:atemp>
<gpxtpx:cad>24</gpxtpx:cad>
</gpxtpx:TrackPointExtension>
</extensions>
</trkpt>
<trkpt lon="126.28602971322834" lat="33.441558703780174">
<time>2015-05-01T21:51:57.000Z</time>
<extensions>
<gpxtpx:TrackPointExtension>
<gpxtpx:atemp>20.0</gpxtpx:atemp>
<gpxtpx:cad>38</gpxtpx:cad>
</gpxtpx:TrackPointExtension>
</extensions>
</trkpt>
<trkpt lon="126.28601093776524" lat="33.441531378775835">
<time>2015-05-01T21:51:58.000Z</time>
<extensions>
<gpxtpx:TrackPointExtension>
<gpxtpx:atemp>20.0</gpxtpx:atemp>
<gpxtpx:cad>39</gpxtpx:cad>
</gpxtpx:TrackPointExtension>
</extensions>
</trkpt>
<trkpt lon="126.29447498358786" lat="33.44377965666354">
<time>2015-05-01T21:55:09.000Z</time>
<extensions>
<gpxtpx:TrackPointExtension>
<gpxtpx:atemp>18.0</gpxtpx:atemp>
<gpxtpx:cad>47</gpxtpx:cad>
</gpxtpx:TrackPointExtension>
</extensions>
</trkpt>
<trkpt lon="126.29451882094145" lat="33.443800024688244">
<time>2015-05-01T21:55:10.000Z</time>
<extensions>
<gpxtpx:TrackPointExtension>
<gpxtpx:atemp>18.0</gpxtpx:atemp>
<gpxtpx:cad>49</gpxtpx:cad>
</gpxtpx:TrackPointExtension>
</extensions>
</trkpt>
</trkseg>
</trk>
</gpx>