На самом деле есть два способа сделать это: один - выполнить двухфазное преобразование, а другой - использовать функцию расширения evaluate
.
Двухфазное преобразование
Сначала вам нужно сгенерировать правильный XSL на основе вашего списка Locations
. Это может выглядеть так:
<xsl:template match="/">
<Data>
<Item Node="/Simulation/@ID">
<xsl:apply-templates select="/Simulation/@ID"/>
</Item>
<Item Node="/Simulation/Loans">
<xsl:apply-templates select="/Simulation/Loans"/>
</Item>
<!-- ... and so on ... -->
</Data>
</xsl:template>
<xsl:template match="node()|@*">
<Value>
<xsl:value-of select="."/>
</Value>
</xsl:template>
Полагаю, у вас нет особых проблем с созданием преобразования, которое будет генерировать этот вывод на основе вашего файла определения XPath, поскольку шаблон довольно прост.
Следующим шагом является применение сгенерированного преобразования к вашему исходному файлу. Вы можете объединить эти два шага в маленькую трубу и получить желаемый результат.
Использование функции расширения
Библиотека EXSLT содержит функцию расширения под названием оценивать , которая помогает в таких случаях, как ваш. Он поддерживается трансформером Xalan из коробки, но не Saxon, насколько я знаю.
Однако существует серьезная проблема с этой функцией - начиная с версии 2.7 Xalan существует ошибка , которая препятствует выполнению нескольких оценок. К сожалению, приведенная ниже таблица стилей затронута, когда я попытался ее запустить Предложение будет изменить версию Xalan на 2.6, если это возможно. Тем не менее, вот таблица стилей, которая будет делать то, что вы хотите, без дополнительной фазы генерации.
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:dyn="http://exslt.org/dynamic" extension-element-prefixes="dyn">
<xsl:variable name="locations" select="document('xpath.xml')/Locations"/>
<xsl:variable name="root" select="/"/>
<xsl:template match="/">
<Data>
<xsl:for-each select="$locations/Location">
<Item Node="{.}">
<xsl:variable name="currentLocation" select="concat('$root', .)"/>
<xsl:apply-templates select="dyn:evaluate($currentLocation)"/>
</Item>
</xsl:for-each>
</Data>
</xsl:template>
<xsl:template match="node()|@*">
<Value>
<xsl:value-of select="."/>
</Value>
</xsl:template>
</xsl:stylesheet>
Предполагается, что документ с определениями Locations находится в одном каталоге и называется xpath.xml
. Обновите document()
использование функции, если это не так.