Я объявил несколько функций расширения 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, даже если они были объявлены позже.
Вы должны знать, что здесь вы имеете дело с внутренними API, которые могут меняться от версии к версии.
XPathContext.getStackFrame()
предоставит вам текущий кадр стека, содержащий локальные переменные; но вам может потребоваться вернуться к контексту вызывающего абонента, используя XPathContext.getCaller()
. У объекта StackFrame
есть метод getStackFrameMap()
, который предоставляет вам объект SlotManager
, который содержит сопоставление имен переменных с целочисленными номерами слотов (имейте в виду, что несколько локальных переменных могут иметь одно и то же имя), а StackFrame.getStackFrameValues()
дает вам массив, содержащий фактические значения переменных ( при условии, что они уже оценены).
При выполнении подобных действий существует множество потенциальных ловушек. Например, вы обнаружите, что некоторые локальные переменные выделяются системой (поддерживаются такие оптимизации, как подъем цикла), а некоторые из объявленных пользователем локальных переменных могут быть оптимизированы. Тот факт, что переменные иногда вычисляются лениво, создает дополнительные проблемы.
Большое спасибо за объяснение! Это позволит мне (с учетом упомянутых вами ловушек) создать XPathVariableResolver из XPathContext, чтобы оценивать выражения XPath в функции расширения Java. Есть ли способ получить выражение XPath, которое использовалось при объявлении переменной?
> Есть ли способ получить выражение XPath, которое использовалось при объявлении переменной? -- Это сложно. Вы могли видеть, к чему вас ведет XPathContext.getOrigin()
; это может быть функция или шаблон, содержащий объявления переменных, дерево выражений которых будет доступно.
Какую именно версию Saxon вы используете?