Когда один и тот же элемент XML соответствует двум шаблонам XSLT через разные XPath, какой шаблон выполняется и почему? - PullRequest
7 голосов
/ 07 октября 2009

Рассмотрим этот XML:

<people>
  <person>
    <firstName>Deane</firstName>
    <lastName>Barker</lastName>
  </person>
</people>

Что если два шаблона XSLT соответствуют элементу через разные XPath ? Я знаю, что если элемент «match» в двух шаблонах идентичен (что никогда не должно происходить, я не думаю), шаблон last сработает.

Однако рассмотрим этот XSL:

<xsl:template match="person/firstName">
    Template #1
</xsl:template>

<xsl:template match="firstName">
    Template #2
</xsl:template>

Элемент "firstName" будет совпадать в любом из этих шаблонов - первый как дочерний элемент "person", а второй автономный.

Я проверил это, и шаблон № 1 выполняется, а шаблон № 2 - нет. Каков принцип действия этого? Я могу думать о трех вещах:

  1. Специфика XPath (весьма сомнительно)
  2. Местоположение в файле XSLT (также сомнительно)
  3. Некоторая перестановка шаблона № 2 шаблоном № 1. Во время выполнения шаблона № 1 происходит что-то, что указывает на то, что шаблон № 2 не должен выполняться.

Ответы [ 4 ]

8 голосов
/ 07 октября 2009

Ваша первая точка на самом деле верна, есть определенный порядок, описанный в https://www.w3.org/TR/1999/REC-xslt-19991116#conflict. Согласно спецификации person/firstName имеет приоритет 0, а firstName имеет приоритет -0,5. Вы также можете указать приоритет самостоятельно, используя атрибут priority в xsl:template.

3 голосов
/ 07 октября 2009

Я знаю, что если элемент "match" включен два шаблона идентичны (которые никогда не должно случиться, я не думаю)

Это может произойти, но не имеет особого смысла делать это и иметь два соответствующих шаблона.

Из спецификации:

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

Другими словами, вы можете получить ошибку или просто использовать последний шаблон в вашем XSLT в зависимости от того, как процессор, который вы используете, был написан для обработки этой ситуации.

2 голосов
/ 09 октября 2009

Обратите внимание, что значение атрибута match равно , а не выражению XPath (хотя оно использует подмножество синтаксиса XPath). Это XSLT шаблон . При отсутствии явных атрибутов priority выбор зависит от того, какой шаблон имеет самый высокий приоритет по умолчанию:

person/firstName имеет приоритет по умолчанию .5

firstName имеет приоритет по умолчанию 0

Таким образом, person/firstName выигрывает.

Полное объяснение того, как работает разрешение конфликтов, можно найти здесь (хотя я рекомендую вам изучить всю главу «Как работает XSLT»): Разрешение конфликтов для правил шаблона

0 голосов
/ 07 октября 2009

Рассмотрите это с учетом контекста. Первый соответствует и изменяет контекст n (поэтому второй не совпадает). Контекст установлен на ПОСЛЕ того, как первый выбран и обработан, поэтому видимый элемент из этого контекста больше не содержит «имя» Если вы хотите, чтобы оба выполнялись, вы можете вместо этого вызывать их, чтобы контекст изменился на самый верх.

 <xsl:template match="people">
    <xsl:apply-templates select="person/firstname"/>
    <xsl:apply-templates select="firstname"/>
</xsl:template>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...