2010-08-19 5 views
9

У меня есть документ XML, которому я подвергаюсь XSLT. Структура аналогична:xsl: применить шаблон только к узлам с определенным значением атрибута

<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> 

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

ответ

7

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.

Во-первых, это 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

Далее, все соответствующие шаблоны правил, которые имеют более низкий приоритет, чем совпадающим правилом шаблона или правила с наивысшим приоритетом исключались из рассмотрения. Приоритет правила шаблона определяется атрибутом приоритета в правиле шаблона . Значение этого параметра должно быть реальным номером (положительным или отрицательным), , соответствующим производственному номеру с необязательным знаковым знаком минус (-).Приоритет по умолчанию вычисляется как следующим образом:

  • Если образец содержит несколько альтернатив, разделенных |, то
    обрабатывают эквивалентно набор правил шаблона, по одному для каждого
    альтернативы.
  • Если образец имеет форму QName предшествует
    ChildOrAttributeAxisSpecifier или имеет вид обработки-инструкции (дословный)
    предшествует ChildOrAttributeAxisSpecifier, то приоритетом является 0.
  • Если образец имеет вид NCName: * предшествует
    ChildOrAttributeAxisSpecifier, тогда приоритет -0.25.
  • В противном случае, если шаблон состоит только из NodeTest , которому предшествует атрибут ChildOrAttributeAxisSpecifier, тогда приоритет равен -0.5.
  • В противном случае приоритет равен 0,5.
+0

Я пробовал ваши предложения, но мне не удалось получить желаемые результаты. Он продолжает применять только один из двух шаблонов к каждому , тогда как цель состоит в том, чтобы применять оба шаблона, но только там, где выполняется условие. См. Мой пересмотренный вопрос с более точным кодом. – alan

+0

Основная проблема, с которой я сталкиваюсь, - это значение, которое я тестирую, принадлежит родительскому элементу узла, к которому я применяю шаблон. – alan

+0

@alan: 'Я пробовал ваши предложения, но мне не удалось получить желаемые результаты. Ну, ** вы изменили вход и желаемый результат **! Лучшей практикой было бы задать другой вопрос. В противном случае вы должны добавить эти новости к своему вопросу, но не заменять. Взгляните на мое редактирование. Если вам что-то непонятно из моей таблицы стилей, просто спросите. – 2010-08-20 14:49:59

0

Возможно вы можете сделать ваши матчи более конкретным:

<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

Спасибо за ваше предложение, я попытался реализовать свои предложения, но я до сих пор получить только один шаблон применяется ко всем узлам . – alan

Смежные вопросы