在 java 中使用 JDOM 在 KML 中的元素之间插入一个新元素

Insert a new element in between elements in KML using JDOM in java

我正在使用 JDOM 创建和修改 KML 文件。每 5 秒我从客户端应用程序收到新的纬度、经度和时间值。我需要修改现有文件并向其中添加最新的纬度、经度和时间值。

XML 文件如下

<?xml version="1.0" encoding="UTF-8"?>
    <kml xmlns="http://www.opengis.net/kml/2.2"
     xmlns:gx="http://www.google.com/kml/ext/2.2">
     <Document>
      <Folder>
       <Placemark>
       <name>deviceA</name>
        <gx:Track>
          <when>2015-06-28T17:02:09Z</when>
          <when>2015-06-28T17:02:35Z</when>
          <gx:coord>3.404258 50.605892 100.000000</gx:coord>
          <gx:coord>3.416446 50.604040 100.000000</gx:coord>
        </gx:Track>
       </Placemark>
       <Placemark>
        <name>deviceB</name>
         <gx:Track>
          <when>2015-06-28T17:02:09Z</when>
          <when>2015-06-28T17:02:35Z</when>
          <gx:coord>3.403133 50.601702 100.000000</gx:coord>
          <gx:coord>3.410171 50.597344 100.000000</gx:coord>
         </gx:Track>
       </Placemark>
      </Folder>
     </Document>
    </kml>

我使用下面的代码插入值

SAXBuilder builder = new SAXBuilder();
File xmlFile = new File(outputFile);
try {

        Document doc = (Document) builder.build(xmlFile);
        Element rootNode = doc.getRootElement();
        Element docNode = rootNode.getChild("Document",ns);
        Element folNode = docNode.getChild("Folder",ns);

        List list = folNode.getChildren("Placemark",ns);

        if(list.size()>0)
        {
            Element node = (Element) list.get(deviceid);
            Element tracknode = node.getChild("Track",ns2);
            List wlist = tracknode.getChildren("when",ns);

            Element newWhen = new Element("when",ns);
            newWhen.setText(whentext);

            Element newCoord = new Element("coord",ns2);
            newCoord.setText(coordtext);

            System.out.println("When size:"+wlist.size());

            int index =0;
            if(wlist.size()==0) index =0;
            else index= wlist.size()+1;

            tracknode.addContent(index, newWhen);
            tracknode.addContent(newCoord);                 
        }

        XMLOutputter outputter = new XMLOutputter(Format.getPrettyFormat());
        FileOutputStream writer = new FileOutputStream(outputFile);
        outputter.output(doc, writer);
        writer.flush();
        writer.close();

} catch (IOException io) {
  System.out.println(io.getMessage());
} catch (JDOMException jdomex) {
  System.out.println(jdomex.getMessage());
}

'gx:coord'部分在元素末尾正确插入,但是需要在元素末尾插入新的when元素'when'。所以我得到了带有标签 'when' 的子列表。获取元素列表的大小并在最后一个元素之后的索引处插入。前两次插入没问题,第三次插入之后我遇到了一个奇怪的问题。新元素 'when' 被插入到现有的 when 元素之间,而不是 when 元素列表的末尾。 例如

<gx:Track>
  <when>2015-06-28T17:02:09Z</when>
  <when>2015-06-28T17:02:44Z</when>
  <when>2015-06-28T17:02:35Z</when>
  <gx:coord>3.404258 50.605892 100.000000</gx:coord>
  <gx:coord>3.416446 50.604040 100.000000</gx:coord>
  <gx:coord>3.429492 50.602078 100.000000</gx:coord>
</gx:Track>

我想在所有现有的 when 元素之后插入新的 'when' 元素。无论如何在 java 中使用 JDOM 可以做到这一点吗?

感谢任何帮助

在 JDOM 中,列表是实时的,甚至是经过过滤的内容列表,其中仅包含父项中的项目子集。

例如,您创建元素节点的代码很好:

        Element newWhen = new Element("when",ns);
        newWhen.setText(whentext);

        Element newCoord = new Element("coord",ns2);
        newCoord.setText(coordtext);

但是,添加它们怎么样:

        Element firstcoord = tracknode.getChild("coord",ns2);
        tracknode.addContent(tracknode.indexOf(firstcoord), newWhen);
        tracknode.addContent(newCoord);
  • 在第一个坐标前加上 when。
  • 在末尾添加 where。

但是,如果轨道是空的,您将需要不同的解决方案。

请注意,您应该在代码中更多地使用泛型。来自 JDOM 的列表值都是符合泛型的,而且很有用。这是我用来测试上述内容的完整(修改后的)代码:

    Document doc = new SAXBuilder().build("locations.kml");

    Namespace ns = Namespace.getNamespace("http://www.opengis.net/kml/2.2");
    Namespace ns2 = Namespace.getNamespace("gx", "http://www.google.com/kml/ext/2.2");

    Element rootNode = doc.getRootElement();
    Element docNode = rootNode.getChild("Document",ns);
    Element folNode = docNode.getChild("Folder",ns);

    List<Element> list = folNode.getChildren("Placemark",ns);

    if(!list.isEmpty())
    {
        Element node = list.get(0);
        Element tracknode = node.getChild("Track",ns2);

        Element newWhen = new Element("when",ns);
        newWhen.setText("WHEN");

        Element newCoord = new Element("coord",ns2);
        newCoord.setText("WHERE");

        Element firstcoord = tracknode.getChild("coord",ns2);
        tracknode.addContent(tracknode.indexOf(firstcoord), newWhen);
        tracknode.addContent(newCoord);

    }

    XMLOutputter outputter = new XMLOutputter(Format.getPrettyFormat());
    outputter.output(doc, System.out);