[英]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.