如何使用Java解析没有第三方库的XML?

时间:2015-05-11 13:28:15

标签: java xml parsing architecture gpx

我正在尝试自己构建一个XML解析器(实际上它是GPX解析器)。

在编写代码时,有些问题突然出现了。

  • 我应该将标签存储为静态变量吗? :有一个关于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>

0 个答案:

没有答案