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