【问题标题】:Insert a new element in between elements in KML using JDOM in java在 Java 中使用 JDOM 在 KML 中的元素之间插入一个新元素
【发布时间】:2015-07-14 10:59:02
【问题描述】:

我正在使用 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来做到这一点?

感谢任何帮助

【问题讨论】:

    标签: java xml kml jdom jdom-2


    【解决方案1】:

    在 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 中的 List 值都符合泛型且有用。这是我用来测试上述内容的完整(修改后的)代码:

        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);
    

    【讨论】:

    • 非常感谢。是的,我会处理我的代码并使用更多的泛型。谢谢你的建议:)你太棒了,先生
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-07-04
    • 2020-08-12
    • 2011-03-15
    • 2016-12-12
    • 2017-01-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多