From fc703b5711782645572aea96bfb7eb08703e8d48 Mon Sep 17 00:00:00 2001 From: "andreas.schildbach" Date: Thu, 30 Sep 2010 14:59:09 +0000 Subject: [PATCH] make parsing more robust git-svn-id: https://public-transport-enabler.googlecode.com/svn/trunk@211 0924bc21-9374-b0fa-ee44-9ff1593b38f0 --- .../schildbach/pte/AbstractEfaProvider.java | 30 +++++++---- src/de/schildbach/pte/util/XmlPullUtil.java | 52 +++++++++++++++++++ 2 files changed, 73 insertions(+), 9 deletions(-) diff --git a/src/de/schildbach/pte/AbstractEfaProvider.java b/src/de/schildbach/pte/AbstractEfaProvider.java index 129b4834..2b40636b 100644 --- a/src/de/schildbach/pte/AbstractEfaProvider.java +++ b/src/de/schildbach/pte/AbstractEfaProvider.java @@ -148,7 +148,7 @@ public abstract class AbstractEfaProvider implements NetworkProvider final List departures = new ArrayList(8); XmlPullUtil.jumpToStartTag(pp, null, "itdDepartureList"); - while (XmlPullUtil.jumpToStartTag(pp, null, "itdDeparture")) + while (XmlPullUtil.nextStartTagInsideTree(pp, null, "itdDeparture")) { if (Integer.parseInt(pp.getAttributeValue(null, "stopID")) == locationId) { @@ -157,24 +157,36 @@ public abstract class AbstractEfaProvider implements NetworkProvider position = "Gl. " + position; departureTime.clear(); - XmlPullUtil.jumpToStartTag(pp, null, "itdDate"); - processItdDate(pp, departureTime); - XmlPullUtil.jumpToStartTag(pp, null, "itdTime"); - processItdTime(pp, departureTime); - XmlPullUtil.jumpToStartTag(pp, null, "itdServingLine"); + if (!XmlPullUtil.nextStartTagInsideTree(pp, null, "itdDateTime")) + throw new IllegalStateException("itdDateTime not found:" + pp.getPositionDescription()); + + if (!XmlPullUtil.nextStartTagInsideTree(pp, null, "itdDate")) + throw new IllegalStateException("itdDate not found:" + pp.getPositionDescription()); + processItdDate(pp, departureTime); + XmlPullUtil.skipRestOfTree(pp); + + if (!XmlPullUtil.nextStartTagInsideTree(pp, null, "itdTime")) + throw new IllegalStateException("itdTime not found:" + pp.getPositionDescription()); + processItdTime(pp, departureTime); + XmlPullUtil.skipRestOfTree(pp); + + XmlPullUtil.skipRestOfTree(pp); + + if (!XmlPullUtil.nextStartTagInsideTree(pp, null, "itdServingLine")) + throw new IllegalStateException("itdServingLine not found:" + pp.getPositionDescription()); final String line = parseLine(pp.getAttributeValue(null, "number"), pp.getAttributeValue(null, "symbol"), pp .getAttributeValue(null, "motType")); - final boolean isRealtime = pp.getAttributeValue(null, "realtime").equals("1"); - final String destination = pp.getAttributeValue(null, "direction"); - final int destinationId = Integer.parseInt(pp.getAttributeValue(null, "destID")); + XmlPullUtil.skipRestOfTree(pp); departures.add(new Departure(!isRealtime ? departureTime.getTime() : null, isRealtime ? departureTime.getTime() : null, line, lineColors(line), null, position, destinationId, destination, null)); } + + XmlPullUtil.skipRestOfTree(pp); } return new QueryDeparturesResult(uri, locationId, location, departures); diff --git a/src/de/schildbach/pte/util/XmlPullUtil.java b/src/de/schildbach/pte/util/XmlPullUtil.java index bfca7e1f..82586319 100644 --- a/src/de/schildbach/pte/util/XmlPullUtil.java +++ b/src/de/schildbach/pte/util/XmlPullUtil.java @@ -297,6 +297,58 @@ public final class XmlPullUtil } } + public static boolean nextStartTagInsideTree(final XmlPullParser pp, final String tagNamespace, final String tagName) + throws XmlPullParserException, IOException + { + if (tagNamespace == null && tagName == null) + throw new IllegalArgumentException("namespace and name argument can not be both null:" + pp.getPositionDescription()); + + if (pp.getEventType() != XmlPullParser.START_TAG && pp.getEventType() != XmlPullParser.END_TAG) + throw new IllegalStateException("expected START_TAG of parent or END_TAG of child:" + pp.getPositionDescription()); + + while (true) + { + final int eventType = pp.next(); + + if (eventType == XmlPullParser.START_TAG) + { + final String name = pp.getName(); + final String namespace = pp.getNamespace(); + boolean matches = (tagNamespace != null && tagNamespace.equals(namespace)) || (tagName != null && tagName.equals(name)); + if (matches) + return true; + + skipSubTree(pp); + pp.require(XmlPullParser.END_TAG, name, namespace); + } + else if (eventType == XmlPullParser.END_TAG) + { + return false; + } + } + } + + public static void skipRestOfTree(final XmlPullParser pp) throws XmlPullParserException, IOException + { + if (pp.getEventType() != XmlPullParser.START_TAG && pp.getEventType() != XmlPullParser.END_TAG) + throw new IllegalStateException("expected START_TAG of parent or END_TAG of child:" + pp.getPositionDescription()); + + while (true) + { + final int eventType = pp.next(); + + if (eventType == XmlPullParser.START_TAG) + { + skipSubTree(pp); + pp.require(XmlPullParser.END_TAG, null, null); + } + else if (eventType == XmlPullParser.END_TAG) + { + return; + } + } + } + /** * This method bypasses all events until it finds a start tag that has passed in namespace (if not null) and * namespace (if not null).