Saxon9: Как получить объявленные переменные из net.sf.saxon.expr.XPathContext в функции расширения Java

Я объявил несколько функций расширения Java, реализовав свою собственную библиотеку net.sf.saxon.functions.JavaExtensionLibrary и передав ее в net.sf.saxon.Configuration и, тем самым, в net.sf.saxon.TransformerFactoryImpl. Пока это работает нормально. Saxon передает объект net.sf.saxon.expr.XPathContext при вызове моих методов. Есть ли способ получить объявленные переменные xsl с их значениями и/или определениями из этого XPathContext? Мне удалось найти только глобальные переменные (объявленные на верхнем уровне таблицы стилей xsl), но не те, которые были объявлены позже в коде XSL. В идеале я хотел бы перечислить переменные.

Я получил глобальные переменные xsl, только вызвав

context.getController().getExecutable().getCompiledGlobalVariables()

Я надеялся получить аналогичную информацию для всех переменных, доступных на данный момент в коде XSL, даже если они были объявлены позже.

🤔 А знаете ли вы, что...
Java позволяет создавать сетевые приложения с использованием сокетов.


1
65
1

Ответ:

Решено

Вы должны знать, что здесь вы имеете дело с внутренними API, которые могут меняться от версии к версии.

XPathContext.getStackFrame() предоставит вам текущий кадр стека, содержащий локальные переменные; но вам может потребоваться вернуться к контексту вызывающего абонента, используя XPathContext.getCaller(). У объекта StackFrame есть метод getStackFrameMap(), который предоставляет вам объект SlotManager, который содержит сопоставление имен переменных с целочисленными номерами слотов (имейте в виду, что несколько локальных переменных могут иметь одно и то же имя), а StackFrame.getStackFrameValues() дает вам массив, содержащий фактические значения переменных ( при условии, что они уже оценены).

При выполнении подобных действий существует множество потенциальных ловушек. Например, вы обнаружите, что некоторые локальные переменные выделяются системой (поддерживаются такие оптимизации, как подъем цикла), а некоторые из объявленных пользователем локальных переменных могут быть оптимизированы. Тот факт, что переменные иногда вычисляются лениво, создает дополнительные проблемы.