Почему xalan не может найти метод который использует ExpressionContext?

122
28 апреля 2018, 15:41

Рассмотрим простой класс:

using org.apache.xalan.extensions;
namespace Foo
{
    public static class Extension
    {
        public static string Bar(ExpressionContext context, string baz)
        {
            return "Hello, world!";
        }
    }
}

Вот так я пытаюсь его использовать:

using javax.xml.transform;
using javax.xml.transform.stream;
public static class Program
{
    static void Main()
    {
        TransformerFactory transformerFactory = new com.sun.org.apache.xalan.@internal.xsltc.trax.TransformerFactoryImpl();
        java.lang.Thread.currentThread().setContextClassLoader(new ikvm.runtime.AppDomainAssemblyClassLoader(typeof(Program).Assembly));
        Transformer t = transformerFactory.newTransformer(new StreamSource("transform.xslt"));
        t.transform(new StreamSource("doc.xml"), new StreamResult(java.lang.System.@out));
    }
}

Входной файл:

<?xml version="1.0" encoding="utf-8" ?>
<root />

Трансформация:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:foo="xalan://cli.Foo.Extension">
  <xsl:output method="xml" indent="yes"/>
  <xsl:template match="/">
    <xsl:value-of select="foo:Bar('baz')" />
  </xsl:template>
</xsl:stylesheet>

Но в итоге получаю вот такую ошибку:

ERROR: 'Cannot find external method 'cli.Foo.Extension.bar' (must be public).' FATAL ERROR: 'Could not compile stylesheet'

В то же время вызов java.lang.Class.forName("cli.Foo.Extension").getMethods() нужный метод находит. В чем дело?

Answer 1

Первая проблема в том, что код использует одновременно два разных Xalan: один встроенный в стандартную библиотеку (пакет com.sun.org.apache.xalan), второй - установленный отдельно (пакет org.apache.xalan). У них разные интерфейсы ExpressionContext, которые несовместимы друг с другом.

Вторая проблема - код использует XSLTC (компилирующую разновидность Xalan), который еще (?) не научили распознавать ExpressionContext. Нужно использовать интерпретирующую версию.

Вот такой код будет работать:

TransformerFactory transformerFactory = new org.apache.xalan.processor.TransformerFactoryImpl();
java.lang.Thread.currentThread().setContextClassLoader(new ikvm.runtime.AppDomainAssemblyClassLoader(typeof(Program).Assembly));
Transformer t = transformerFactory.newTransformer(new StreamSource("transform.xslt"));
t.transform(new StreamSource("doc.xml"), new StreamResult(java.lang.System.@out));
READ ALSO
Получение данных из Mysql C#

Получение данных из Mysql C#

Необходимо получить balance по userid

125
c# system.IO.Directory.GetDirectories нужен метод для сортировке по Дате

c# system.IO.Directory.GetDirectories нужен метод для сортировке по Дате

я начинающий в c#Написана довольно большая консольная программа в ней множество раз получается массив методом system

123
Перенос строки при шифровке

Перенос строки при шифровке

Есть приложение калькулятор, в котором все вычисления будут шифроваться, сохраняться в текстовый файл (каждое вычисление на новой строке),...

161