java саксофон парсер искажает атрибуты для xml 1.1
Я использую классы саксофона Java для анализа XML-файла. Если в xml-файле указана версия 1.0, все работает нормально, но если в нем указана версия 1.1, некоторые атрибуты искажаются, что дает неправильные результаты, но не вызывает каких-либо исключений.
Мой XML-файл в основном выглядит так:
<?xml version="1.1" encoding="UTF-8" ?>
<gpx>
<trk>
<name>Name of the track</name>
<trkseg>
<trkpt lat="12.3456789" lon="1.2345678">
<ele>1234</ele>
<time>2013-03-26T12:34:56Z</time>
<speed>0</speed>
</trkpt>
... and then 419 further identical copies of this trkpt
</trkseg>
</trk>
</gpx>
Так что, когда я использую sax для анализа этого файла, я ожидаю найти 420 trkpt-тегов, каждый из которых должен иметь атрибуты lat и lon. В частности, я ожидаю найти 420 "lat" атрибутов, которые все "12.3456789".
Для анализа я создаю объект-обработчик и передаю ему поток в этот локальный файл:
SAXParser saxParser = SAXParserFactory.newInstance().newSAXParser();
inStream = new FileInputStream(file);
saxParser.parse(inStream, handler);
System.out.println("done");
Класс обработчика расширяется org.xml.sax.helpers.DefaultHandler
и просто есть один метод, startElement
реагировать на открытие тега trkpt:
public void startElement(String uri, String localName, String qName, Attributes attributes)
{
if (qName.equals("trkpt") && attributes != null
&& attributes.getLength() == 2
&& attributes.getValue(0).charAt(0) != '1')
{
// The trkpt tag has two attributes
// but the value of the first one doesn't begin with '1'
System.out.println(attributes.getQName(0) + " = " + attributes.getValue(0));
}
super.startElement(uri, localName, qName, attributes);
}
Так каков результат? Если XML-файл имеет версию 1.0, то все, что я вижу, это "сделано". Было найдено 420 тегов trkpt, все они имели два атрибута, первый всегда назывался "lat", и значение этого атрибута всегда начиналось с "1", как я и ожидал. Большой!
Если XML-файл изменен, чтобы указать version="1.1"
в первой строке я получаю следующий вывод:
lat = :34.56Z</t
lat = :56Z</time
done
Поэтому, хотя все мои 420 очков должны быть идентичны, два из них дали мне совершенно неправильное значение атрибута. Никаких исключений не выбрасывается. Еще 420 trkpts были найдены, и у всех было два атрибута, называемых "lat" и "lon". Как ни странно, значения lon всегда в порядке.
Я создал этот xml-файл в текстовом редакторе путем прямого копирования / вставки первого trkpt, поэтому я уверен, что все значения идентичны, я уверен, что в xml-файле нет точек с забавными значениями атрибутов, и я ' Я уверен, что нет никаких не символьных значений символов или кодов сущностей или чего-то еще странного в файле.
Я пробовал использовать Sun JRE6, OpenJDK6 и OpenJDK7 на трех разных машинах с двумя разными ОС. Так что либо я делаю что-то не так, либо этот конкретный XML-файл как-то несовместим с xml1.1, либо существует широко распространенная ошибка саксофона (что кажется маловероятным, так как я ожидаю, что это повлияет на многих людей). Опять же, обратите внимание, с xml1.0 все работает нормально. Также обратите внимание, что в числе 420 нет ничего особенного, просто если файл содержит только 100 записей, они все анализируются правильно. Если у вас есть несколько тысяч записей, то определенное количество из них получает свое первое значение атрибута искаженным таким образом. Длина значения атрибута всегда кажется правильной, но она вытаскивает символы из неправильной точки в файле. Переполнение индекса возможно?
Я попытался удалить все метки скорости, но проблема все еще сохраняется, если у вас есть достаточно trkpts. Он также чувствителен к дополнительным пробелам, поэтому проблема возникает с разными точками или возвращает разные значения атрибутов, если я добавляю разрывы строк между trkpts.
1 ответ
Эта ошибка присутствовала в анализаторе XML JDK в течение многих лет, и ни Sun, ни Oracle не проявили интереса к ее исправлению. Я настоятельно рекомендую использовать анализатор XML Apache Xerces в предпочтении.