Следует ли применять поведение XSLT3 без имени xsl: mode on-no-match к элементу, для которого режим не соответствует, но режим указан в apply-templates? - PullRequest
1 голос
/ 14 января 2020

Этот вопрос проще описать в качестве примера, а не в виде текста.

Со следующим XML

<?xml version="1.0" encoding="UTF-8"?>
<tests>
    <test>1</test>
    <test>2</test>
</tests>

Если я запускаю следующий XSLT3

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    expand-text="true"
    version="3.0">

    <xsl:output method="xml" />
    <xsl:mode on-no-match="shallow-copy" />
    <!--<xsl:mode name="test" on-no-match="shallow-copy"/>-->

    <xsl:template match="/">
        <mytests>
            <xsl:apply-templates/>
            <xsl:apply-templates mode="test"/>
        </mytests>
    </xsl:template>

    <xsl:template match="tests" mode="test">
        <modetest>
            <xsl:apply-templates mode="#current"/>
        </modetest>
    </xsl:template>
</xsl:stylesheet>

Я получаю следующий вывод в Saxon 9

<?xml version="1.0" encoding="UTF-8"?>
<mytests>
    <tests>
        <test>1</test>
        <test>2</test>
    </tests>
    <modetest>
            1
            2
    </modetest>
</mytests>

Вы можете видеть, что при использовании режима "test" мы не получаем вывод тестового элемента, только содержимое этих элементов. Не существует шаблона для элемента «test» с режимом «test».

Я бы догадался, что, поскольку нет совпадения, включился бы on-no-match = "shallow-copy" из режима xsl: без атрибута имени? Я предположил, что безымянный xsl: mode будет применяться ко всем несоответствиям, даже если режим действует (если другой xsl: mode не определен с именем, соответствующим текущему режиму). Если вы раскомментируете xsl: mode name = "test" on-no-match = "shallow-copy", тогда все работает как положено (поэтому обходного пути не требуется, спасибо), но это означает, что в XSLT с множеством примененных режимов -templates, мне нужно определить много-много именованных режимов xsl: просто для того, чтобы получить поведение шаблона идентификации.

Может кто-нибудь указать, если я делаю что-то не так или это ведет себя согласно w3 C Спецификация?

Ответы [ 2 ]

1 голос
/ 14 января 2020

"Я предполагал, что безымянный xsl: mode будет применяться ко всем несоответствиям, даже если режим включен"

Извините, ваше предположение будет неверным. Подумайте об этом так: существует режим с именем #unnamed, и любой элемент xsl:template, xsl:apply-templates или xsl:mode без атрибута @mode по умолчанию равен mode="#unnamed". (Это приблизительное значение, оно становится более сложным, когда задано default-mode, но это базовая концепция c.)

Нет способа определить свойства множества режимов "навалом", вам нужно одно xsl:mode объявление для режима.

0 голосов
/ 14 января 2020

Встроенная обработка по умолчанию для любого режима: text-only-copy, см. https://www.w3.org/TR/xslt-30/#modes "Если используется имя режима (например, в объявлении шаблона xsl: или в xsl: apply- инструкция шаблонов), и в таблице стилей не отображается объявление этого режима, режим неявно объявляется со свойствами по умолчанию "и https://www.w3.org/TR/xslt-30/#built -in-rule

Существует шесть наборов из встроенных шаблонов правил доступны. Выбранный набор является свойством режима, выбранного инструкцией xsl:apply-templates. Это свойство устанавливается с помощью атрибута on-no-match объявления xsl: mode, который принимает одно из шести значений deep-copy, shallow-copy, deep-skip, shallow-skip, text-only-copy или fail, значение по умолчанию text-only-copy.

Встроенная обработка по умолчанию в XSLT 2 или 1 не отличается.

Если необходимо объявить преобразование идентификаторов отдельно с отдельными объявлениями xsl:mode кажется слишком громоздким, вы, конечно, также можете написать шаблон

<xsl:template match="@* | node()" mode="#all">
   <xsl:copy>
      <xsl:apply-templates select="@*" mode="#current"/>
      <xsl:apply-templates mode="#current"/>
   </xsl:copy>
</xsl:template>

https://www.w3.org/TR/xslt-30/#using -modes

...