У меня есть два XML, один для определения шаблонов для объектов моего приложения. и другой с реальными объектами. В основном в каждом объекте изменяются только несколько значений, поэтому я хотел предоставить какой-то механизм шаблонов и применить XSL для преобразования их в окончательный вариант.
Это образец объекта:
<config>
<objects>
<object code="1000" name="object1">
<template name="decoration" buyCoins="60" />
</object>
</objects>
И это пример шаблона для этого объекта:
<config xmlns:template="object-template">
<templates>
<template name="decoration">
<connection type="make" />
<placeable width="1" length="1" moveable="true" collision="D" />
<buyable>
<requirement template:coins="buyCoins"/>
<reward xp="1" />
</buyable>
<sellable>
<reward coins="1"/>
</sellable></template></templates></config>
Это мой текущий XSL:
<xsl:variable name="templates" select="document('../templates.xml')/config/templates//template" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="//template">
<xsl:variable name="itemTemplate" select="."/>
<xsl:variable name="templateName" select="@name"/>
<xsl:variable name="selectedTemplate" select="$templates[@name = $templateName]/*" />
<xsl:for-each select="$selectedTemplate">
<!-- This part is only a test to get the values that I need -->
<xsl:for-each select=".//@*[namespace-uri() = 'object-template']">
<xsl:variable name="attributeName" select="name()"/>
<xsl:variable name="attributeValue" select="."/>
<xsl:variable name="finalValue" select="$itemTemplate/@*[local-name() = $attributeValue]"/>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
<xsl:template match="comment()"/>
Мне просто нужно сделать следующее:
- Итерация каждого элемента, содержащего тег шаблона
- Для каждого из них получите соответствующий шаблон документа шаблона
- Скопируйте все внутри шаблона в объект (*)
- Заменить значения атрибутов внутри элемента (теперь с вставленным шаблоном) реальным значением в исходном шаблоне (**)
Пояснение:
(*) Применить
<template name="test"><node></template>
до
<object><template name="test"></object>
становится
<object><node></object>
(**) В исходном примере выше значение buyCoins тега шаблона элемента должно заменить значение шаблона текста «buyCoins» перед отправкой его в вывод. Для удобства поиска и для того, чтобы избежать рег. эксп. Я использую пространства имен. Итак, что я делаю в XSL - это поиск всех атрибутов внутри шаблона с правильным пространством имен и поиск значений.
Значение "60" должно быть помещено вместо "buyCoins" внутри атрибута coins.
Моя проблема в том, что я не понимаю, как копировать все (я думаю, это называется идентификационной копией), но заменяю нужное мне значение.
Любая помощь будет оценена, спасибо !!!
UPDATE:
Токовый выход:
<config xmlns:template="item-template">
<objects>
<object code="1000" name="object1" type="decorations">
</object>
</object>
Если я поставлю:
<xsl:copy-of select="."/>
ниже:
<xsl:for-each select="$selectedTemplate">
Тогда я получаю:
<objects>
<object code="1000" name="object1">
<connection type="make" /><placeable width="1" length="1" moveable="true" collision="D" />
<buyable>
<requirement template:coins="buyCoins"/>
<reward xp="1" />
</buyable>
<sellable>
<reward coins="1"/>
</sellable>
</object></objects>
Это первая часть того, что мне нужно, чтобы поместить в каждый элемент вывода содержимое связанного с ним шаблона. У меня проблемы с заменой значений.
Эти строки дерева в XSL представляют данные, которые мне нужны:
<xsl:variable name="attributeName" select="name()"/>
<xsl:variable name="attributeValue" select="."/>
<xsl:variable name="finalValue" select="$itemTemplate/@*[local-name() = $attributeValue]"/>
Для единственного элемента в этом примере это содержимое каждой переменной:
attributeName будет содержать «template: coins»
attributeValue будет содержать «buyCoins»
finalValue будет содержать "60"
Мне нужно поместить finalValue вместо attributeValue в тег этого атрибута name.
В этот момент я застрял: (
Спасибо!
Обновление 2:
Чтобы избежать недоразумений, вот ТОЧНЫЙ вывод, который мне нужен:
<objects>
<object code="1000" name="object1">
<connection type="make" /><placeable width="1" length="1" moveable="true" collision="D" />
<buyable>
<requirement coins="60"/>
<reward xp="1" />
</buyable>
<sellable>
<reward coins="1"/>
</sellable>
</object></objects>
Вместо «buyCoins» в атрибуте монеты мне нужно, чтобы оно было «60» (значение в файле входных объектов).
Кроме того, наилучший возможный вывод должен также удалить шаблоны пространств имен атрибутов, потому что XSL-файл знает только, какие атрибуты нужно изменить.