apply-templates предупреждение о неоднозначном совпадении - PullRequest
0 голосов
/ 11 октября 2019

Я получаю предупреждение

неоднозначное совпадение правил

от процессора для шаблонов copyReference и преобразование идентичности .

<xsl:template name="processChildNodes">
    <xsl:param name="El"/>

    <xsl:for-each select="$El/node()">
        <xsl:choose>
            <xsl:when test="@sameas">
                <xsl:apply-templates mode="copyReference" select="id(substring-after(@sameas, '#'))"/>
            </xsl:when>         
            <xsl:otherwise>
                <xsl:copy-of select="." />
            </xsl:otherwise>
        </xsl:choose>
    </xsl:for-each>
</xsl:template>


<xsl:template match="*" mode="copyReference" name="copyReference">
    <xsl:copy>
        <xsl:apply-templates select="@* except (@stem.dir, @stem.sameas)"/>
    </xsl:copy>
</xsl:template>



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

Вот фрагмент XML:

<layer>         
        <note oct="3" pname="b" stem.dir="up" stem.sameas="#note_17544b" xml:id="note_17544"/>          
</layer>
<layer>
    <note oct="4" pname="d" xml:id="note_17592"/>
    <note sameas="#note_17544" xml:id="note_17544b"/>   
</layer>

Я хочу просто скопировать узел, на который ссылается атрибут @ sameas, без @stem. dir и @ stem.sameas. Могут быть разные узлы local-names (), к которым будет применяться. Поэтому я бы не стал указывать имена узлов в атрибуте @ match шаблона copyReference . Я думал, что если я пропущу нужные мне узлы с помощью @ select-attribute, а также добавлю @mode, он будет соответствовать только тому, что мне нужно. И на самом деле это работает, но когда я получаю предупреждение, что-то должно быть не так.

1 Ответ

1 голос
/ 11 октября 2019

node() является сокращением для *|text()|comment()|processing-instruction(), и поэтому, поскольку шаблон идентификации содержит mode="#all", он будет соответствовать любому элементу с тем же приоритетом, что и шаблон «copyReference», когда используется режим «copyReference». .

Решение зависит от того, что еще делает ваша таблица стилей, но есть ряд возможностей

  1. Удалить mode="#all" из шаблона идентификации (это будет работать, только если не былодругие режимы в вашем XSLT)
  2. Добавьте priority="2" в шаблон «copyReference», чтобы при использовании режима «copyReference» ваш конкретный шаблон получал приоритет.
  3. Change <xsl:apply-templates mode="copyReference"... вместо xsl:for-each и покончить с соответствием шаблона.
  4. Измените шаблон "copyReference", чтобы он явно совпадал с "note", а не "*", так как это придаст ему более высокий приоритет (ноэто, очевидно, предполагает, что вам нужно будет сопоставить только note элементов)
...