Нет, невозможно сохранить переменную в цикле for-each и использовать ее позже.
Это потому, что переменные имеют однократную запись в XSLT (после установки они неизменяемы) и строго ограничены родительским элементом. Как только обработка выходит из цикла for-each, переменная исчезает.
XSLT не работает как императивный язык программирования, но вы, похоже, пытаетесь здесь это сделать. Вам не нужно <xsl:for-each>
в 98% всех случаев, и вы не должны его использовать, потому что это забивает ваше представление о том, как работает XSLT. Чтобы улучшить свой код XSLT, избавьтесь от всех имеющихся у вас циклов <xsl:for-each>
(я имею в виду все они) и используйте вместо них шаблоны:
<xsl:template match="Foundation.Core.Class">
<xsl:apply-templates select="
Foundation.Core.Classifier.feature/Foundation.Core.Attribute
" />
</xsl:template>
<xsl:template match="Foundation.Core.Attribute">
<owl:DatatypeProperty rdf:ID="{Foundation.Core.ModelElement.name}">
<rdfs:domain rdf:resource="{
ancestor::Foundation.Core.Class[1]/Foundation.Core.ModelElement.name[1]
}" />
</owl:DatatypeProperty>
</xsl:template>
(Я не уверен, что вышесказанное - то, что вы на самом деле хотите, ваш вопрос довольно двусмысленный.)
Обратите внимание на использование оси XPath ancestor
для ссылки на элемент выше в иерархии (кажется, вы хотите <Foundation.Core.ModelElement.name>
родительского класса).
PS: Ваш XML невероятно раздут и сильно избыточен из-за структурированных имен элементов. Структура должна быть из ... ну ... структура , а не из таких элементов, как <Foundation.Core.Classifier.feature>
. Я не уверен, что вы можете что-нибудь с этим сделать.
Дополнительно:
Для решения проблемы xmi.id
/ xmi.idref
лучше всего использовать ключ XSL:
<!-- this indexes all elements by their @xmi.id attribute -->
<xsl:key name="kElementByIdref" match="*[@xmi.id]" use="@xmi.id" />
<!-- now you can do this -->
<xsl:template match="Foundation.Core.DataType">
<dataTypeName>
<!-- pull out the corresponding element from the key, output its value -->
<xsl:value-of select="key('kElementByIdref', @xmi.idref)" />
</dataTypeName>
</xsl:template>
Чтобы лучше понять, как ключи работают внутри, вы можете прочитать этот ответ, который я дал ранее . Не беспокойтесь слишком сильно вопросом, просто прочитайте нижнюю часть моего ответа, я объяснил ключи в терминах JavaScript.