xsl: apply-template только для узлов с определенным значением атрибута

У меня есть документ 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>

Проблема в том, что ко всем узлам элементов применяется один и тот же шаблон. Как применить шаблон только к конкретным узлам?

10
задан alan 20 August 2010 в 13:51
поделиться

2 ответа

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.
9
ответ дан 4 December 2019 в 01:55
поделиться

Возможно, вы сможете уточнить свои совпадения:

<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>
0
ответ дан 4 December 2019 в 01:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: