У меня есть документ XML, который я подвергается XSLT. Структура похожа на:
<root>
<item value="1">
<object/>
</item>
<item value="2" />
<object/>
</item>
</root>
Моя цель - получить преобразованный XML, похожий на:
<root>
<parent>
<object-one value-one="1"/>
</parent>
<parent>
<object-two value-two="2"/>
</parent>
</root>
Мой XSLT похож на:
<xsl:apply-templates select="object" />
<xsl:template match="object">
<xsl:call-template name="1" />
<xsl:call-template name="2" />
</xsl:template>
<xsl:template name="1" match="object[item/@value = '1'">
<xsl:element name="object-one" namespace="http://something.org">
<xsl:attribute name="_Description">
<xsl:value-of select="@_Type"/>
</xsl:attribute>
<xsl:attribute name="_Type">
<xsl:value-of select="@_Amount"/>
</xsl:attribute>
</xsl:element>
</xsl:template>
<xsl:template name="2" match="object[item/@value = '2'">
<xsl:element name="object-two" namespace="http://something.org">
<xsl:attribute name="OriginalAmount">
<xsl:value-of select="@_Amount"/>
</xsl:attribute>
</xsl:element>
</xsl:template>
Проблема в том, что ко всем узлам элементов применяется один и тот же шаблон. Как применить шаблон только к конкретным узлам?
EDIT: Теперь для другого входного образца (исправленного на хорошо сформированный):
<root>
<item value="1">
<object/>
</item>
<item value="2" >
<object/>
</item>
</root>
Эта таблица стилей:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:num="number" extension-element-prefixes="num">
<num:num>one</num:num>
<num:num>two</num:num>
<xsl:template match="root">
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="item">
<parent>
<xsl:apply-templates/>
</parent>
</xsl:template>
<xsl:template match="object">
<xsl:variable name="vTextNumber" select="document('')/*/num:*[number(current()/../@value)]"/>
<xsl:element name="object-{$vTextNumber}">
<xsl:attribute name="value-{$vTextNumber}">
<xsl:value-of select="../@value"/>
</xsl:attribute>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
Выход:
<root>
<parent>
<object-one value-one="1" />
</parent>
<parent>
<object-two value-two="2" />
</parent>
</root>
EDIT 2: Итак, что не так в вашем фрагменте таблицы стилей? Похоже, что вы не знаете, как процессор разрешает применение правил шаблона, а также XPath navegation.
Во-первых, этот object[item/@value = '1']
будет соответствовать только этому виду ввода
<object>
<item value="1"/>
</object>
Во-вторых, рассмотрим эти три правила
1 -
<xsl:template match="object">
</xsl:template>
2 -
<xsl:template name="1" match="object[../@value = '1']">
</xsl:template>
3 -
<xsl:template name="2" match="object[../@value = '2']">
</xsl:template>
С вашим последним вводом, первый object
элемент (в порядке документа) будет соответствовать правилам 1 и 2, а затем процессор решит применить правило 2. Почему? Из http://www.w3.org/TR/xslt#conflict
Далее, все совпадающие правила шаблона, которые имеют более низкий приоритет, чем совпадающее правило шаблона или правила с самым высоким приоритетом, исключаются из рассмотрения. Приоритет правила шаблона определяется атрибутом атрибут priority в шаблонном правило. Его значение должно быть реальным число (положительное или отрицательное), соответствующее производственному числу с необязательным ведущим знаком минус (-). приоритет по умолчанию вычисляется следующим образом следующим образом:
- Если шаблон содержит несколько альтернатив, разделенных |, то он
обрабатывается эквивалентно набору правил шаблона, по одному для каждой
альтернативы.- Если шаблон имеет форму QName, которому предшествует
ChildOrAttributeAxisSpecifier или имеет форму processing-instruction(Literal)
, которой предшествует ChildOrAttributeAxisSpecifier, то приоритет равен 0.- Если шаблон имеет форму NCName:*, которой предшествует a
ChildOrAttributeAxisSpecifier, то приоритет равен -0.25.- В противном случае, если шаблон состоит только из NodeTest которому предшествует ChildOrAttributeAxisSpecifier, то приоритет будет -0.5.
- Иначе, приоритет равен 0.5.
Возможно, вы сможете уточнить свои совпадения:
<xsl:template name="item1" match="item[@value=1]">
<xsl:element name="item" namespace="http://something.org">
<xsl:attribute name="_Description">
<xsl:value-of select="@_Type"/>
</xsl:attribute>
<xsl:attribute name="_Type">
<xsl:value-of select="@_Amount"/>
</xsl:attribute>
</xsl:element>
</xsl:template>
<xsl:template name="item2" match="item[@value=2]">
<xsl:element name="item2_item" namespace="http://something.org">
<xsl:attribute name="OriginalAmount">
<xsl:value-of select="@_Amount"/>
</xsl:attribute>
</xsl:element>
</xsl:template>