在.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
只是输入文件的副本,因此在这个简化的示例中,我运行文件的一个实例,在样式表中读取另一个实例。
Goold‘xsltproc
正在提取正确的属性值("bar")。默认处理器(Xalan)的ant.xslt
抛出一个ArrayIndexOutOfBoundsException
(我想在查找元素名内的冒号时),.The问题只有在引用nodeSet
时才会出现,比如在<xsl:value-of>
元素中。
<xsl:template>
在所有情况下都匹配,使用前缀。
我的问题是:我是不是在Xalan上碰到了一个bug,或者我是不是做错了什么?
我知道与名称空间前缀有关的各种工作,比如使用[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
Invokation通过shell命令gradlew mytask
通过Gradle,使用使用内置ant.xslt
任务的Gradle内置Ant。
build.gradle
tasks.register('mytask') {
doLast {
ant.xslt(
baseDir: '.',
in: 'input.xsd',
out: 'out.xml',
style: 'stylefile.xsl'
)
}
}
发布于 2022-11-10 16:19:56
xslt/xml代码很好(适用于Saxon)。所以,这要么是运行转换的方式,要么是您正在使用的Xalan版本中的一个bug。
无论如何,Xalan不应该抛出ArrayIndexOutOfBounds
异常。这大概是堆栈跟踪上的Xalan代码吧?
https://stackoverflow.com/questions/74391430
复制相似问题