[英]Java remove nodes from XML
There are a couple similar questions, I read all of them but can't get it to work. 有几个类似的问题,我都读过,但是无法解决。
I hava a XML file (a GPS track log), looking something like this: 我有一个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>
which gets merged with some other data (heart rate) frome an other file. 它与其他文件中的其他一些数据(心率)合并在一起。 I just modified some existing code for my purpose, and this is already working.
我只是出于我的目的修改了一些现有代码,并且这已经在起作用。
Now i want to delete some trackpoints completely, if they are out of a certain time range. 现在,如果它们不在某个时间范围内,我想完全删除它们。 I'm able to identify those trackpoints and (for testing) add a "comment" to the entries I want to delete, but I wasn't able to remove them.
我能够识别出这些跟踪点,并(为了进行测试)在要删除的条目中添加“注释”,但是无法删除它们。
Here's the code: 这是代码:
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);
}
}
}
}
//.... below this the data is written out to the file... // ....在此之下,数据被写到文件中...
the result loos something like this at the moment: 结果目前出现类似以下情况:
.....
<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>
..... .....
Thanks for help! 感谢帮助!
Edit: 编辑:
I tried things like: 我尝试过类似的事情:
trackPt.getParentNode().removeChild(trackPt);
but this results in a NullPoiterException 但这会导致NullPoiterException
Node removeNode = sections.item(i); mergedDoc.removeChild(removeNode);
, but this results in a org.w3c.dom.DOMExeption: NOT_FOUND_ERR ,但这会导致org.w3c.dom.DOMExeption:NOT_FOUND_ERR
mergedDoc.getElementsByTagName("trkseg").item(0).removeChild(trackPt);
and I also also get a java.lang.NullPointerException 而且我还得到了一个java.lang.NullPointerException
You don't show how you have tried. 您不会显示自己的尝试方式。 But the general rule is : a child element has to be removed from its parent and not from itself.
但是一般的规则是:子元素必须从其父元素中删除,而不是从其自身中删除。
1)You can retrieve the parent by invoking getParentNode()
( Node
interface). 1)您可以通过调用
getParentNode()
( Node
接口)来检索父级。
2)Then from the parent node you can invoke removeChild()
with as parameter the child node to remove. 2)然后,您可以从父节点调用带有要删除的子节点作为参数的
removeChild()
。
I read somewhere else, that removing elements within a loop using them the can cause unpredictable results, therefore I solved the problem by deleting them in a separate loop: 我在其他地方读到,在循环中使用元素删除元素会导致不可预测的结果,因此我通过在单独的循环中删除元素来解决了问题:
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.