В файле .xsl я хочу использовать узлы из отдельного файла ("foo.xsd"). Файл .xsl использует явный префикс пространства имен, внешний файл не использует пространство имен по умолчанию, а скорее полагается на него. Их URI пространства имен совпадают.
Чтение в узлах с ant.xslt
следующим выражением XPath позже приводит к ArrayIndexOutOfBounds
исключению
document('foo.xsd')/xsd:schema/xsd:*
пока работает при удалении последней ссылки на префикс пространства имен
document('foo.xsd')/xsd:schema/*
Вот минимальный пример, который воспроизводит проблему. Входной файл преобразования
<?xml version = "1.0" encoding = "UTF-8"?>
<schema xmlns = "http://www.w3.org/2001/XMLSchema">
<element name = "bar"/>
</schema>
и файл преобразования .xsl
<?xml version = "1.0" encoding = "UTF-8"?>
<xsl:stylesheet
xmlns:xsl = "http://www.w3.org/1999/XSL/Transform"
xmlns:xsd = "http://www.w3.org/2001/XMLSchema"
version = "1.0">
<xsl:variable name = "nodeSet" select = "document('foo.xsd')/xsd:schema/xsd:*[@name]"/>
<xsl:template match = "/xsd:schema/xsd:element">
<xsl:value-of select = "$nodeSet/@name"/>
</xsl:template>
</xsl:stylesheet>
Упомянутый foo.xsd
— это просто копия входного файла, поэтому в этом урезанном примере я запускаю один экземпляр файла и читаю другой экземпляр в таблице стилей.
Старый добрый xsltproc
извлекает правильное значение атрибута ("bar"). ant.xslt
с процессором по умолчанию (Xalan) выдает ArrayIndexOutOfBoundsException
(я предполагаю, что при поиске двоеточия внутри имени элемента). Проблема возникает только при ссылке на nodeSet
, как в элементе <xsl:value-of>
.
<xsl:template>
соответствует во всех случаях, используя префиксы.
У меня такой вопрос: я столкнулся с ошибкой в Xalan или вообще что-то делаю не так?
Я знаю о различных обходных путях, касающихся префиксов пространств имен, таких как использование [local-name() = 'element']
и т. д., поэтому, пожалуйста, не публикуйте ответы в этом ключе. Я ищу общий ответ, должно ли это работать (например, в соответствии со спецификациями).
Справочный материал
Stacktrace (часть), которая намекает на Xalan:
...
Caused by: javax.xml.transform.TransformerException: java.lang.ArrayIndexOutOfBoundsException: Index -1 out of bounds for length 512
at java.xml/com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:783)
at java.xml/com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:370)
at org.apache.tools.ant.taskdefs.optional.TraXLiaison.transform(TraXLiaison.java:201)
at org.apache.tools.ant.taskdefs.XSLTProcess.process(XSLTProcess.java:870)
... 126 more
Caused by: java.lang.ArrayIndexOutOfBoundsException: Index -1 out of bounds for length 512
at java.xml/com.sun.org.apache.xml.internal.utils.SuballocatedIntVector.elementAt(SuballocatedIntVector.java:441)
at java.xml/com.sun.org.apache.xml.internal.dtm.ref.DTMDefaultBase._firstch(DTMDefaultBase.java:523)
at java.xml/com.sun.org.apache.xalan.internal.xsltc.dom.SAXImpl.access$200(SAXImpl.java:73)
at java.xml/com.sun.org.apache.xalan.internal.xsltc.dom.SAXImpl$NamespaceChildrenIterator.next(SAXImpl.java:1431)
at java.xml/com.sun.org.apache.xalan.internal.xsltc.dom.CurrentNodeListIterator.setStartNode(CurrentNodeListIterator.java:158)
at java.xml/com.sun.org.apache.xalan.internal.xsltc.dom.StepIterator.setStartNode(StepIterator.java:97)
at java.xml/com.sun.org.apache.xalan.internal.xsltc.dom.StepIterator.setStartNode(StepIterator.java:97)
at java.xml/com.sun.org.apache.xalan.internal.xsltc.dom.DupFilterIterator.setStartNode(DupFilterIterator.java:97)
at java.xml/com.sun.org.apache.xalan.internal.xsltc.dom.CachedNodeListIterator.setStartNode(CachedNodeListIterator.java:57)
at jdk.translet/die.verwandlung.test.topLevel()
at jdk.translet/die.verwandlung.test.transform()
at java.xml/com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet.transform(AbstractTranslet.java:624)
at java.xml/com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:776)
... 129 more
Вызов осуществляется через Gradle через команду оболочки gradlew mytask
с использованием встроенного в Gradle Ant с использованием его встроенной ant.xslt
задачи.
построить.градле:
tasks.register('mytask') {
doLast {
ant.xslt(
baseDir: '.',
in: 'input.xsd',
out: 'out.xml',
style: 'stylefile.xsl'
)
}
}
Тестирование вашего кода с помощью Xalan 2.7.2 с использованием командной строки дало ожидаемый результат, поэтому проблема, похоже, в другом. Сообщение об ошибке также не похоже на XSLT.
Ваш код xslt/xml в порядке (работает с Saxon). Так что это либо что-то в том, как вы проводите трансформацию, либо это ошибка в версии Xalan, которую вы используете.
В любом случае Ксалан не должен генерировать исключение ArrayIndexOutOfBounds
. Предположительно, это код Xalan в трассировке стека?
Спасибо, что изучили это. Я обновил вопрос, включив в него информацию о трассировке стека и вызове. Я мог видеть, что это зависит от версии Xalan, но, несмотря на все мои усилия, я еще не понял, какая версия Xalan используется в этом техническом стеке Gradle/Ant/java.xml/JRE/....
Извините, больше ничем помочь не могу. Трассировка стека является довольно убедительным доказательством ошибки Xalan.
Я бы сказал, что IndexOfOutBoundsException — это своего рода ошибка. Однако я не могу воспроизвести проблему с версией Xalan, включенной в текущую версию XML-редактора oXygen.