Как получить номер строки, где происходит ошибка компиляции Saxon XSLT? - PullRequest
0 голосов
/ 18 октября 2019

Я использую Saxon PE 9.7.0.18.

Я компилирую XSLT с кодом, подобным следующему:

import javax.xml.transform.TransformerFactory;
import net.sf.saxon.TransformerFactoryImpl;

...

StringBuilder errorString = new StringBuilder();
ErrorListener errorListener = new ErrorListener() {
    public void warning(TransformerException e) { 
        errorString.append("\nERROR: ").append(e.getMessageAndLocation()); }
    public void error(TransformerException e) { 
        errorString.append("\nWARN: ").append(e.getMessageAndLocation()); }
    public void fatalError(TransformerException e) { 
        errorString.append("\nFATAL: ").append(e.getMessageAndLocation()); }
};

TransformerFactoryImpl transformerFactory = 
    (TransformerFactoryImpl) TransformerFactory.newInstance(
        TransformerFactoryImpl.class.getName(), 
        DocumentGenerator.class.getClassLoader());
transformerFactory.setErrorListener(errorListener);
Templates templates = transformerFactory.newTemplates(new DOMSource(xslt));
xsltTransformerFactory = new XsltTransformerFactory() {
    @SneakyThrows(TransformerConfigurationException.class)
    @Override public Transformer newTransformer() { return templates.newTransformer(); }
};
Transformer transformer = xsltTransformerFactory.newTransformer();

К сожалению, если файл XSLT недействителен, это приводит к ошибкам, таким как:

FATAL: Required item type of first operand of '/' is node(); 
   supplied value has item type xs:string

Файлы XSLT иногда имеют длину в тысячи строк, поскольку они генерируются из другой системы. Было бы очень полезно узнать, в какой строке произошла такая ошибка. (Только что я выполнил «бинарный поиск», многократно удаляя половину исходного файла XSLT и проверяя, не произошла ли ошибка, чтобы найти ошибочную строку. Как только я нашел строку, ошибка в файле XSLT была довольно очевидной! )

Я уверен, что процессор XSLT должен знать строку, которую он обрабатывает?

В отладчике я вижу, что TransformerException содержит AttributeLocator, но оба lineNumber и *Атрибуты 1016 * равны -1, что, вероятно, объясняет, почему метод getMessageAndLocation() не включает местоположение.

Я понимаю, что во время компиляции Saxon может существовать флаг времени компиляции, чтобы повлиять на это, но я несам не скомпилировал Saxon, я скачал его с https://www.saxonica.com/download/java.xml, когда приобрел редакцию PE.

Как узнать номер строки ошибок XSLT?

1 Ответ

1 голос
/ 18 октября 2019

Вы предоставили ввод таблицы стилей из дерева DOM, а DOM не хранит номера строк.

Если у вас нет веских причин использовать DOM, лучше избегать этого. DOM также плохо отслеживает базовый URI, что, помимо прочего, влияет на разрешение xsl:include и xsl:import. Кроме того, он не является поточно-ориентированным.

Используйте StreamSource или SAXSource в предпочтении.

...