是dyn:评估已知在Xalan-J 2.7.1中存在问题的扩展函数吗?

我很难过为什么以下示例程序拒绝正确应用我的样式表。 看来dyn:evaluate在Xalan 2.7.1中的dyn:evaluate是拒绝处理某些XPath变量。

在类路径中使用xalan-j运行以下程序会产生以下结果:

 package com.testing2.xslt; import java.io.*; import java.util.logging.*; import javax.xml.transform.*; import javax.xml.transform.stream.*; public class DynEvaluateTransform { private static final String XSLT = "" + "\n" + "\n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " dyn:evaluate available\n" + " \n" + " \n" + " dyn:evaluate not available\n" + " \n" + " \n" + " input.xml content:\n" + " \n" + " {}\n" + "  \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + ""; private static final String EXAMPLE = "" + "\n" + " \n" + "  \n" + "  \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + ""; private static final String INPUT = "" + "\n" + "\n" + " \n" + " \n" + " \n" + ""; private TransformerFactory xalanTransFact; public DynEvaluateTransform() { xalanTransFact = new org.apache.xalan.processor.TransformerFactoryImpl(); xalanTransFact.setURIResolver(new Resolver()); } private void applyTransform() { // XSLT(EXAMPLE) --> output.xml // ^ // | // INPUT OutputStreamWriter writer = null; try { String outputFileName = DynEvaluateTransform.getLocalFileName("output.xml"); File file = new File(outputFileName); writer = new OutputStreamWriter(new FileOutputStream(file), "UTF-8"); System.out.println(org.apache.xalan.Version.getVersion()); Transformer transformer = xalanTransFact.newTransformer(new StreamSource(new StringReader(XSLT))); transformer.setOutputProperty(OutputKeys.INDENT, "yes"); transformer.setOutputProperty(OutputKeys.METHOD, "xml"); transformer.setOutputProperty(OutputKeys.ENCODING, "utf-8"); transformer.transform( new StreamSource(new StringReader(EXAMPLE)), new StreamResult(writer)); } catch (UnsupportedEncodingException ex) { Logger.getLogger(DynEvaluateTransform.class.getName()).log(Level.SEVERE, null, ex); } catch (FileNotFoundException ex) { Logger.getLogger(DynEvaluateTransform.class.getName()).log(Level.SEVERE, null, ex); } catch (TransformerConfigurationException ex) { Logger.getLogger(DynEvaluateTransform.class.getName()).log(Level.SEVERE, null, ex); } catch (TransformerException ex) { Logger.getLogger(DynEvaluateTransform.class.getName()).log(Level.SEVERE, null, ex); } finally { if (writer != null) { try { writer.close(); } catch (IOException ex) { } } } } private void rebuildInput() { // ignore - this just writes the input.xml file, so we can later reference it StringReader strReader = null; OutputStreamWriter fileWriter = null; try { String fileName = getLocalFileName("input.xml"); strReader = new StringReader(INPUT); File file = new File(fileName); fileWriter = new OutputStreamWriter(new FileOutputStream(file), "UTF-8"); TransformerFactory factory = TransformerFactory.newInstance(); Transformer transformer = factory.newTransformer(); transformer.setOutputProperty(OutputKeys.INDENT, "yes"); transformer.setOutputProperty(OutputKeys.METHOD, "xml"); transformer.transform( new StreamSource(strReader), new StreamResult(fileWriter)); } catch (UnsupportedEncodingException ex) { Logger.getLogger(DynEvaluateTransform.class.getName()).log(Level.SEVERE, null, ex); } catch (FileNotFoundException ex) { Logger.getLogger(DynEvaluateTransform.class.getName()).log(Level.SEVERE, null, ex); } catch (TransformerConfigurationException ex) { Logger.getLogger(DynEvaluateTransform.class.getName()).log(Level.SEVERE, null, ex); } catch (TransformerException ex) { Logger.getLogger(DynEvaluateTransform.class.getName()).log(Level.SEVERE, null, ex); } catch (IOException ex) { Logger.getLogger(DynEvaluateTransform.class.getName()).log(Level.SEVERE, null, ex); } finally { if (strReader != null) { strReader.close(); } if (fileWriter != null) { try { fileWriter.close(); } catch (IOException ex) { } } } } public static void main(String[] args) { DynEvaluateTransform det = new DynEvaluateTransform(); det.rebuildInput(); det.applyTransform(); } private static String getLocalFileName(String href) { String name = System.getProperty("user.dir"); if (!name.endsWith(File.separator)) { name += File.separator; } name += href; return name; } private static class Resolver implements URIResolver { @Override public Source resolve(String href, String base) throws TransformerException { if ("input.xml".equals(href)) { return new StreamSource(new File(DynEvaluateTransform.getLocalFileName(href))); } else { return null; } } } } 
 Xalan Java 2.7.1 SystemId Unknown; Line #14; Column #30; dyn:evaluate available SystemId Unknown; Line #20; Column #22; input.xml content: SystemId Unknown; Line #22; Column #26; {org:example:foo}a SystemId Unknown; Line #22; Column #26; {org:example:foo}b SystemId Unknown; Line #22; Column #26; {org:example:foo}c SystemId Unknown; Line #25; Column #26; true() SystemId Unknown; Line #26; Column #26; true SystemId Unknown; Line #25; Column #26; false() SystemId Unknown; Line #26; Column #26; false SystemId Unknown; Line #25; Column #26; false() or true() SystemId Unknown; Line #26; Column #26; true SystemId Unknown; Line #25; Column #26; $selections SystemId Unknown; Line #26; Column #26; SystemId Unknown; Line #25; Column #26; $selections/* SystemId Unknown; Line #26; Column #26; SystemId Unknown; Line #25; Column #26; $selections/*[local-name()='a'] SystemId Unknown; Line #26; Column #26; SystemId Unknown; Line #25; Column #26; $selections/element::node()[local-name()='a'] SystemId Unknown; Line #26; Column #26; SystemId Unknown; Line #25; Column #26; local-name($selections/*) SystemId Unknown; Line #26; Column #26; SystemId Unknown; Line #25; Column #26; not($selections/*[local-name()='a' and namespace-uri()='org:example:foo']) SystemId Unknown; Line #26; Column #26; true SystemId Unknown; Line #25; Column #26; $selections/*[local-name()='b' and namespace-uri()='org:example:foo'] SystemId Unknown; Line #26; Column #26; SystemId Unknown; Line #25; Column #26; $selections/*[local-name()='c' and namespace-uri()='org:example:foo'] SystemId Unknown; Line #26; Column #26; SystemId Unknown; Line #25; Column #26; not($selections/*[local-name()='a' and namespace-uri()='org:example:foo']) or ($selections/*[local-name()='b' and namespace-uri()='org:example:foo'] and $selections/*[local-name()='c' and namespace-uri()='org:example:foo']) SystemId Unknown; Line #26; Column #26; true 

示例程序使用提供的转换(XSLT)转换示例输入(EXAMPLE),该转换将通过document()函数打开的输入文件(INPUT, input.xml )作为“参数”。 此输入文件包含一组使用XPath表达式(位于EXAMPLE中)测试的元素。

程序的输出表明支持dyn:evaluate函数,正确读取input.xml ,正确评估简单的XPath表达式,但只要涉及XPath变量就会中断。

下面涉及的所有文件的可读版本。

input.xml中

       

                

XSLT

        dyn:evaluate available   dyn:evaluate not available   input.xml content:  {}        

Xalan不支持dyn:evaluate参数中的XPath变量吗? 我是否正确定义了表达式? 尝试在选择Xalan的情况下在oXygen中运行此样式表,报告java.lang.RuntimeException: ElemTemplateElement error: Function not supported! 何时首次遇到XPath变量。

编辑:

我已经重写了这个问题,以澄清我的实际问题。

正如所担心的那样,XPAN变量中的结果树片段似乎不受dyn:evaluate支持dyn:evaluate在Xalan 2.7.1中dyn:evaluate 。 请注意,具有非结果树片段值的变量有效。

我编写了自己的扩展函数( dyn:evaluate equivalent)来评估XPath表达式,但它也无法处理变量中的结果树片段(收到this method is not yet supportedexception)。 这可能是JAXP提供的XPath引擎实现的限制。

也许它适用于不同的XPath引擎实现。

我放弃了尝试使这项工作,并将避免在dyn:evaluate正在运行时将结果树片段填充到XPath变量中。 我将简单地提供通过xsl:param字符串值来评估我的条件所需的信息,而不是使用外部XML文件的艰难方式。 Xalan的扩展函数将检查选择是否实际存在。

Interesting Posts