使用 SAX 解析日期 Java
Parsing dates with SAX Java
我在使用 SAX 解析 gpx 文件的日期时遇到问题。不知何故,它无法正确获取某些节点的 <time>
标记。大部分节点没问题,其他标签好像没问题
我在不同的 gpx 文件上进行测试,它总是在相同文件的相同节点上失败,并且没有特殊字符或任何东西。而且是周期性的。
我正在打印错误旁边的节点号。而第3列是当前错误与上次错误的差值
它通常在第一个错误 800 到 1000 左右开始。如您所见,日期没有被正确选择,出于某种原因它们被修剪了。
这是我的经纪人
package ec.com.mapachedev.webmapper.gpx;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class SAXFileHandler extends DefaultHandler {
private String reading;
private List<SAXTrack> tracks;
private List<SAXWayPoint> waypoints;
private List<SAXTrackPoint> trackpoints;
private SAXTrack track;
private SAXTrackPoint trackPoint;
private SAXWayPoint wayPoint;
private LocalDateTime fechaExtraido;
private LocalDateTime fechaIni;
private LocalDateTime fechaFin;
private DateTimeFormatter parser = DateTimeFormatter
.ofPattern("[yyyy-MM-dd'T'HH:mm:ss.SSS'Z']" + "[yyyy-MM-dd'T'HH:mm:ss'Z']");
private boolean isWaypoint = false;
private boolean isTrackPoint = false;
private int cont = 0;
public SAXFileHandler() {
super();
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
try {
if (qName.equals("trkpt")) {
trackPoint = new SAXTrackPoint();
isWaypoint = false;
isTrackPoint = true;
try {
trackPoint.setLat(Double.parseDouble(attributes.getValue("lat")));
trackPoint.setLon(Double.parseDouble(attributes.getValue("lon")));
} catch (Exception e) {
System.out.println("Error " + e.getMessage());
}
} /*
* else if (qName.equals("trkseg")) {
*
* }
*/else if (qName.equals("trk")) {
track = new SAXTrack();
isWaypoint = false;
isTrackPoint = false;
} else if (qName.equals("wpt")) {
isWaypoint = true;
isTrackPoint = false;
wayPoint = new SAXWayPoint();
try {
wayPoint.setLat(Double.parseDouble(attributes.getValue("lat")));
wayPoint.setLon(Double.parseDouble(attributes.getValue("lon")));
} catch (Exception e) {
System.out.println("Error " + e.getMessage());
}
} else if (qName.equals("gpx")) {
tracks = new ArrayList<SAXTrack>();
waypoints = new ArrayList<SAXWayPoint>();
isWaypoint = false;
isTrackPoint = false;
}
} finally {
// no matter the node, we empty the StringBuilder accumulator when
// we start
// a new node.
reading=null;
}
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
if (qName.equals("trkpt")) {
track.getPuntos().add(trackPoint);
} else if (qName.equals("speed")) {
try {
trackPoint.setVelocidad(Double.parseDouble(reading));
} catch (Exception e) {
System.out.println("Error " + e.getMessage());
}
} else if (qName.equals("time") && isTrackPoint) {
System.out.println("Time Track " + reading + " "
+ cont++);/*
* try { cont++;
* //System.out.println("Time Track " + reading
* + " "+cont++);
* trackPoint.setFecha(LocalDateTime.parse(
* reading, parser)); // Siempre guardamos la
* ultima fecha y si es la primer vez que //
* grabamos fechas tambien ponemos fechaInicial
* fechaFin = trackPoint.getFecha(); if
* (fechaIni == null) fechaIni =
* trackPoint.getFecha(); } catch (Exception e)
* { System.out.println("Error " +
* e.getMessage()+" " +cont); }
*/
} else if (qName.equals("ele") && isTrackPoint) {
try {
trackPoint.setEle(Double.parseDouble(reading));
} catch (Exception e) {
System.out.println("Error " + e.getMessage());
}
} else if (qName.equals("name") && isTrackPoint) {
// System.out.println("Nombre: "+reading);
trackPoint.setNombre(reading);
} else if (qName.equals("desc") && !isWaypoint && !isTrackPoint) {
track.setDesc(reading);
} else if (qName.equals("name") && !isWaypoint && !isTrackPoint) {
track.setName(reading);
} else if (qName.equals("desc") && isWaypoint) {
wayPoint.setDesc(reading);
} else if (qName.equals("cmt") && isWaypoint) {
wayPoint.setCmt(reading);
} else if (qName.equals("name") && isWaypoint) {
wayPoint.setCmt(reading);
} else if (qName.equals("time") && isWaypoint) {
System.out.println("Time WP " + reading);
wayPoint.setFecha(LocalDateTime.parse(reading, parser));
} else if (qName.equals("ele") && isWaypoint) {
try {
wayPoint.setEle(Double.parseDouble(reading));
} catch (Exception e) {
System.out.println("Error " + e.getMessage());
}
} else if (qName.equals("trk")) {
tracks.add(track);
} else if (qName.equals("time") && tracks.size() == 0) {
System.out.println("Time GPX " + reading);
fechaExtraido = LocalDateTime.parse(reading, parser);
}
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
reading = new String(ch, start, length);
}
public List<SAXTrack> getTracks() {
return tracks;
}
public void setTracks(List<SAXTrack> tracks) {
this.tracks = tracks;
}
public List<SAXWayPoint> getWaypoints() {
return waypoints;
}
public void setWaypoints(List<SAXWayPoint> waypoints) {
this.waypoints = waypoints;
}
public List<SAXTrackPoint> getTrackpoints() {
return trackpoints;
}
public void setTrackpoints(List<SAXTrackPoint> trackpoints) {
this.trackpoints = trackpoints;
}
public SAXTrack getTrack() {
return track;
}
public void setTrack(SAXTrack track) {
this.track = track;
}
public SAXTrackPoint getTrackPoint() {
return trackPoint;
}
public void setTrackPoint(SAXTrackPoint trackPoint) {
this.trackPoint = trackPoint;
}
public SAXWayPoint getWayPoint() {
return wayPoint;
}
public void setWayPoint(SAXWayPoint wayPoint) {
this.wayPoint = wayPoint;
}
public LocalDateTime getFechaExtraido() {
return fechaExtraido;
}
public void setFechaExtraido(LocalDateTime fechaExtraido) {
this.fechaExtraido = fechaExtraido;
}
public LocalDateTime getFechaIni() {
return fechaIni;
}
public void setFechaIni(LocalDateTime fechaIni) {
this.fechaIni = fechaIni;
}
public LocalDateTime getFechaFin() {
return fechaFin;
}
public void setFechaFin(LocalDateTime fechaFin) {
this.fechaFin = fechaFin;
}
public DateTimeFormatter getParser() {
return parser;
}
public void setParser(DateTimeFormatter parser) {
this.parser = parser;
}
}
您使用的 java.time
class 和您的日期时间格式模式似乎不匹配。
您的所有日期时间实例都声明为类型:LocalDateTime
,因此它们将期望传递给 parse
函数的文本值遵循:DateTimeFormatter.ISO_LOCAL_DATE_TIME
格式,即:2011-12-03T10:15:30
.
来自 LocalDateTime
JavaDoc:
A date-time without a time-zone in the ISO-8601 calendar system, such
as 2007-12-03T10:15:30.
请注意格式 DOES 包含:'T'
,但 NOT 包含:'Z'
。这与您问题中包含的所有错误消息一致;这些错误消息中引用的所有文本值都包含 'Z'
字符。
如果你调整传递给的格式模式:DateTimeFormatter.ofPattern
删除'Z'
字符,我相信你的问题会得到解决。
我更改了我的代码以使用它。
https://mappingdev.wordpress.com/2011/09/22/parsing-gpxxml-files-with-sax/
只需在代码中将 localName 更改为 name,一切正常
我在使用 SAX 解析 gpx 文件的日期时遇到问题。不知何故,它无法正确获取某些节点的 <time>
标记。大部分节点没问题,其他标签好像没问题
我在不同的 gpx 文件上进行测试,它总是在相同文件的相同节点上失败,并且没有特殊字符或任何东西。而且是周期性的。
我正在打印错误旁边的节点号。而第3列是当前错误与上次错误的差值
它通常在第一个错误 800 到 1000 左右开始。如您所见,日期没有被正确选择,出于某种原因它们被修剪了。
这是我的经纪人
package ec.com.mapachedev.webmapper.gpx;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class SAXFileHandler extends DefaultHandler {
private String reading;
private List<SAXTrack> tracks;
private List<SAXWayPoint> waypoints;
private List<SAXTrackPoint> trackpoints;
private SAXTrack track;
private SAXTrackPoint trackPoint;
private SAXWayPoint wayPoint;
private LocalDateTime fechaExtraido;
private LocalDateTime fechaIni;
private LocalDateTime fechaFin;
private DateTimeFormatter parser = DateTimeFormatter
.ofPattern("[yyyy-MM-dd'T'HH:mm:ss.SSS'Z']" + "[yyyy-MM-dd'T'HH:mm:ss'Z']");
private boolean isWaypoint = false;
private boolean isTrackPoint = false;
private int cont = 0;
public SAXFileHandler() {
super();
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
try {
if (qName.equals("trkpt")) {
trackPoint = new SAXTrackPoint();
isWaypoint = false;
isTrackPoint = true;
try {
trackPoint.setLat(Double.parseDouble(attributes.getValue("lat")));
trackPoint.setLon(Double.parseDouble(attributes.getValue("lon")));
} catch (Exception e) {
System.out.println("Error " + e.getMessage());
}
} /*
* else if (qName.equals("trkseg")) {
*
* }
*/else if (qName.equals("trk")) {
track = new SAXTrack();
isWaypoint = false;
isTrackPoint = false;
} else if (qName.equals("wpt")) {
isWaypoint = true;
isTrackPoint = false;
wayPoint = new SAXWayPoint();
try {
wayPoint.setLat(Double.parseDouble(attributes.getValue("lat")));
wayPoint.setLon(Double.parseDouble(attributes.getValue("lon")));
} catch (Exception e) {
System.out.println("Error " + e.getMessage());
}
} else if (qName.equals("gpx")) {
tracks = new ArrayList<SAXTrack>();
waypoints = new ArrayList<SAXWayPoint>();
isWaypoint = false;
isTrackPoint = false;
}
} finally {
// no matter the node, we empty the StringBuilder accumulator when
// we start
// a new node.
reading=null;
}
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
if (qName.equals("trkpt")) {
track.getPuntos().add(trackPoint);
} else if (qName.equals("speed")) {
try {
trackPoint.setVelocidad(Double.parseDouble(reading));
} catch (Exception e) {
System.out.println("Error " + e.getMessage());
}
} else if (qName.equals("time") && isTrackPoint) {
System.out.println("Time Track " + reading + " "
+ cont++);/*
* try { cont++;
* //System.out.println("Time Track " + reading
* + " "+cont++);
* trackPoint.setFecha(LocalDateTime.parse(
* reading, parser)); // Siempre guardamos la
* ultima fecha y si es la primer vez que //
* grabamos fechas tambien ponemos fechaInicial
* fechaFin = trackPoint.getFecha(); if
* (fechaIni == null) fechaIni =
* trackPoint.getFecha(); } catch (Exception e)
* { System.out.println("Error " +
* e.getMessage()+" " +cont); }
*/
} else if (qName.equals("ele") && isTrackPoint) {
try {
trackPoint.setEle(Double.parseDouble(reading));
} catch (Exception e) {
System.out.println("Error " + e.getMessage());
}
} else if (qName.equals("name") && isTrackPoint) {
// System.out.println("Nombre: "+reading);
trackPoint.setNombre(reading);
} else if (qName.equals("desc") && !isWaypoint && !isTrackPoint) {
track.setDesc(reading);
} else if (qName.equals("name") && !isWaypoint && !isTrackPoint) {
track.setName(reading);
} else if (qName.equals("desc") && isWaypoint) {
wayPoint.setDesc(reading);
} else if (qName.equals("cmt") && isWaypoint) {
wayPoint.setCmt(reading);
} else if (qName.equals("name") && isWaypoint) {
wayPoint.setCmt(reading);
} else if (qName.equals("time") && isWaypoint) {
System.out.println("Time WP " + reading);
wayPoint.setFecha(LocalDateTime.parse(reading, parser));
} else if (qName.equals("ele") && isWaypoint) {
try {
wayPoint.setEle(Double.parseDouble(reading));
} catch (Exception e) {
System.out.println("Error " + e.getMessage());
}
} else if (qName.equals("trk")) {
tracks.add(track);
} else if (qName.equals("time") && tracks.size() == 0) {
System.out.println("Time GPX " + reading);
fechaExtraido = LocalDateTime.parse(reading, parser);
}
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
reading = new String(ch, start, length);
}
public List<SAXTrack> getTracks() {
return tracks;
}
public void setTracks(List<SAXTrack> tracks) {
this.tracks = tracks;
}
public List<SAXWayPoint> getWaypoints() {
return waypoints;
}
public void setWaypoints(List<SAXWayPoint> waypoints) {
this.waypoints = waypoints;
}
public List<SAXTrackPoint> getTrackpoints() {
return trackpoints;
}
public void setTrackpoints(List<SAXTrackPoint> trackpoints) {
this.trackpoints = trackpoints;
}
public SAXTrack getTrack() {
return track;
}
public void setTrack(SAXTrack track) {
this.track = track;
}
public SAXTrackPoint getTrackPoint() {
return trackPoint;
}
public void setTrackPoint(SAXTrackPoint trackPoint) {
this.trackPoint = trackPoint;
}
public SAXWayPoint getWayPoint() {
return wayPoint;
}
public void setWayPoint(SAXWayPoint wayPoint) {
this.wayPoint = wayPoint;
}
public LocalDateTime getFechaExtraido() {
return fechaExtraido;
}
public void setFechaExtraido(LocalDateTime fechaExtraido) {
this.fechaExtraido = fechaExtraido;
}
public LocalDateTime getFechaIni() {
return fechaIni;
}
public void setFechaIni(LocalDateTime fechaIni) {
this.fechaIni = fechaIni;
}
public LocalDateTime getFechaFin() {
return fechaFin;
}
public void setFechaFin(LocalDateTime fechaFin) {
this.fechaFin = fechaFin;
}
public DateTimeFormatter getParser() {
return parser;
}
public void setParser(DateTimeFormatter parser) {
this.parser = parser;
}
}
您使用的 java.time
class 和您的日期时间格式模式似乎不匹配。
您的所有日期时间实例都声明为类型:LocalDateTime
,因此它们将期望传递给 parse
函数的文本值遵循:DateTimeFormatter.ISO_LOCAL_DATE_TIME
格式,即:2011-12-03T10:15:30
.
来自 LocalDateTime
JavaDoc:
A date-time without a time-zone in the ISO-8601 calendar system, such as 2007-12-03T10:15:30.
请注意格式 DOES 包含:'T'
,但 NOT 包含:'Z'
。这与您问题中包含的所有错误消息一致;这些错误消息中引用的所有文本值都包含 'Z'
字符。
如果你调整传递给的格式模式:DateTimeFormatter.ofPattern
删除'Z'
字符,我相信你的问题会得到解决。
我更改了我的代码以使用它。 https://mappingdev.wordpress.com/2011/09/22/parsing-gpxxml-files-with-sax/
只需在代码中将 localName 更改为 name,一切正常