簡體   English   中英

Java從XML刪除節點

[英]Java remove nodes from XML

有幾個類似的問題,我都讀過,但是無法解決。

我有一個XML文件(GPS跟蹤日志),看起來像這樣:

  <trk>
<name>Aktueller Track : 07 FEB 2017 19:17</name>
<extensions>
  <gpxx:TrackExtension>
    <gpxx:DisplayColor>DarkGray</gpxx:DisplayColor>
  </gpxx:TrackExtension>
</extensions>
<trkseg>
  <trkpt lat="48.052169037982821" lon="16.298389015719295">
    <ele>142.88999999999999</ele>
    <time>2017-02-07T18:34:34Z</time>
  </trkpt>
  <trkpt lat="48.052171971648932" lon="16.298409970477223">
    <ele>147.22</ele>
    <time>2017-02-07T18:34:39Z</time>
  </trkpt>

它與其他文件中的其他一些數據(心率)合並在一起。 我只是出於我的目的修改了一些現有代碼,並且這已經在起作用。

現在,如果它們不在某個時間范圍內,我想完全刪除它們。 我能夠識別出這些跟蹤點,並(為了進行測試)在要刪除的條目中添加“注釋”,但是無法刪除它們。

這是代碼:

private void create(File outputFile) throws TransformerConfigurationException, TransformerException, ParseException, FileNotFoundException {
            Document mergedDoc = (Document) gpxDoc.cloneNode(true);
            NodeList sections = mergedDoc.getElementsByTagName("trkpt");
            int nTr = sections.getLength();
            for (int i = 0; i < nTr; i++) {

                Element trackPt = (Element) sections.item(i);
                Node timeNode = Util.getChildByName(trackPt, "time");
                if (timeNode != null) {
                    String st = timeNode.getFirstChild().getNodeValue();
                    long time = Util.toTime(st);

                    int heartRate = trackPoints.getHeartRateForTime(time + tcxTimeOffset);
                    if (heartRate > 0) {
                        Element exframe = mergedDoc.createElement("extensions");
                        Element extension = mergedDoc.createElement("gpxtpx:TrackPointExtension"); 
                        Element hr = mergedDoc.createElement("gpxtpx:hr");
                        hr.appendChild(mergedDoc.createTextNode(String.valueOf(heartRate)));//
                        extension.appendChild(hr);
                        exframe.appendChild(extension);
                        trackPt.appendChild(exframe);
                    }
                    if(crop){
                        if (time < (tcxStartTime.getTime()-5000) || time > (tcxEndTime.getTime()+5000)){
                            //for testing
                            Element remove = mergedDoc.createElement("delete");
                            trackPt.appendChild(remove);
                        }
                    }
                }
            }

// ....在此之下,數據被寫到文件中...

結果目前出現類似以下情況:

.....
<trkpt lat="48.052186975255609" lon="16.29835800267756">
    <ele>206.81999999999999</ele>
    <time>2017-02-07T18:37:28Z</time>
  <delete/>
</trkpt>
<trkpt lat="48.052185969427228" lon="16.298419022932649">
    <ele>206.34</ele>
    <time>2017-02-07T18:38:30Z</time>
    <extensions>
        <gpxtpx:TrackPointExtension>
             <gpxtpx:hr>83</gpxtpx:hr>
        </gpxtpx:TrackPointExtension>
    </extensions>
</trkpt>

.....

感謝幫助!

編輯:

我嘗試過類似的事情:

trackPt.getParentNode().removeChild(trackPt);

但這會導致NullPoiterException

Node removeNode = sections.item(i); mergedDoc.removeChild(removeNode); ,但這會導致org.w3c.dom.DOMExeption:NOT_FOUND_ERR

mergedDoc.getElementsByTagName("trkseg").item(0).removeChild‌​(trackPt); 而且我還得到了一個java.lang.NullPointerException

您不會顯示自己的嘗試方式。 但是一般的規則是:子元素必須從其父元素中刪除,而不是從其自身中刪除。

1)您可以通過調用getParentNode()Node接口)來檢索父級。

2)然后,您可以從父節點調用帶有要刪除的子節點作為參數的removeChild()

我在其他地方讀到,在循環中使用元素刪除元素會導致不可預測的結果,因此我通過在單獨的循環中刪除元素來解決了問題:

NodeList sections = mergedDoc.getElementsByTagName("trkpt");
Set<Element> targetElements = new HashSet<Element>();
int nTr = sections.getLength();
for (int i = 0; i < nTr; i++) {
    Element trackPt = (Element) sections.item(i);

    //................
    //removed not relevant code for answer.....
    //.......

    //
    if (time < (tcxStartTime.getTime()-5000) || time > (tcxEndTime.getTime()+5000)){
        targetElements.add(trackPt);
    }

}


for (Element trackPt: targetElements) {
    trackPt.getParentNode().removeChild(trackPt);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM