Понимание соответствия 'применять-шаблонов'

Я корректен в размышлении что apply-templates объявление должно соответствовать всем шаблонам, которые могли возможно быть применены для выбора?

Например, учитывая следующий фрагмент XML:

<doc>
  <foo bar="1" baz="2">boz</foo>
</doc>

и следующая таблица стилей:

<xsl:template match="/">
  <xsl:apply-templates select="foo" mode="xyz" />
</xsl:template>

<xsl:template mode="xyz" match="foo[bar='1']">
  abc
</xsl:template>

<xsl:template mode="xyz" match="foo[baz='2']">
  def
</xsl:template>

Я ожидал бы, что вывод будет:

abc
def

Это корректно?

5
задан Phillip B Oldham 26 January 2010 в 10:33
поделиться

3 ответа

Нет, вы не получаете оба выхода, поскольку будет выбран только один шаблон. См. Эта страница для правил по разрешению конфликтов, если есть несколько возможных шаблонов.

После исправления вашего стилей (аналогично тому, как Рубенс сделал это, но с тем же режимами) это обычно приведет к подаче последнего шаблона в вашем файле XSLT, поэтому вывод будет def . Это связано с тем, что две шаблоны имеют одинаковый приоритет, и если ваш процессор XSLT не останавливается с ошибкой, стандарт требует, чтобы он применил последнюю:

Это ошибка, если это оставляет более одного соответствия правила шаблона. Процессор XSLT может сигнализировать об ошибке; Если он не сигнализирует об ошибке, он должен восстановиться, выбрав, изреди соответствующих правил шаблона, которые остаются, то, что происходит последним в стиле таблицы.

6
ответ дан 13 December 2019 в 22:07
поделиться

Если вы Хотите, чтобы ваши шаблоны соответствуют оба атрибута , то вам просто нужно будет настроить Match XPath XPath , чтобы выбрать атрибуты и поместите отношение к Фу в предикате; Вместо того, чтобы иметь два противоречивых шаблона, соответствующие элементу с такой же специфичностью (которые имеют одинаковый приоритет).

<?xml version="1.0" encoding="UTF-8"?>
  <xsl:stylesheet
   version="1.0"
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes" encoding="UTF-8"/>

<xsl:template match="/">
  <xsl:apply-templates select="doc/foo"  />
</xsl:template>

<!--When templates match on foo, apply templates for it's attributes -->
<xsl:template match="foo">
    <xsl:apply-templates select="@*"/>
</xsl:template>

<!--Unique template match for the bar attribute -->
<xsl:template match="@bar[parent::foo and .='1']">
  abc
</xsl:template>

<!--Unique template match for the baz attribute -->
<xsl:template match="@baz[parent::foo and .='2']">
  def
</xsl:template>

</xsl:stylesheet>
4
ответ дан 13 December 2019 в 22:07
поделиться

Если вы исправите этот код XSLT (у вас есть некоторые проблемы с фильтром) и пробежали его, вы должны увидеть:

Def

Почему? будут совпадать первым шаблоном , что удовлетворяет вашему состоянию матча. Если у вас есть два шаблона, вам следует отличаться, чем с помощью этого Режим атрибут или с помощью Приоритет Атрибут:

<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:template match="/doc">
        <xsl:apply-templates select="foo" mode="2" />
    </xsl:template>

    <xsl:template mode="1" match="foo[@bar='1']">
        abc
    </xsl:template>

    <xsl:template mode="2" match="foo[@baz='2']">
        def
    </xsl:template>

</xsl:stylesheet>
0
ответ дан 13 December 2019 в 22:07
поделиться
Другие вопросы по тегам:

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