Почему нет выбора в первых apply-шаблонах - PullRequest
5 голосов
/ 13 июня 2011

Я пытаюсь понять apply-templates, но я не понимаю, почему я не пишу здесь select = "nodename" в apply-templates: (я думаю о первых шаблонах apply под коллекцией My CD)

Фрагмент из входного документа:

<?xml version="1.0" encoding="ISO-8859-1"?>
<catalog>
    <cd>
        <title>Empire Burlesque</title>
        <artist>Bob Dylan</artist>
        <country>USA</country>
        <company>Columbia</company>
        <price>10.90</price>
        <year>1985</year>
    </cd>
    <cd>
        <title>Hide your heart</title>
        <artist>Bonnie Tyler</artist>
        <country>UK</country>
        <company>CBS Records</company>
        <price>9.90</price>
        <year>1988</year>
    </cd>
    <cd>
        <title>Greatest Hits</title>
        <artist>Dolly Parton</artist>
        <country>USA</country>
        <company>RCA</company>
        <price>9.90</price>
        <year>1982</year>
    </cd>

XSLT:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
  <html>
  <body>
  <h2>My CD Collection</h2>
  <xsl:apply-templates/>
  </body>
  </html>
</xsl:template>

<xsl:template match="cd">
  <p>
  <xsl:apply-templates select="title"/>
  <xsl:apply-templates select="artist"/>
  </p>
</xsl:template>

<xsl:template match="title">
  Title: <span style="color:#ff0000">
  <xsl:value-of select="."/></span>
  <br />
</xsl:template>

<xsl:template match="artist">
  Artist: <span style="color:#00ff00">
  <xsl:value-of select="."/></span>
  <br />
</xsl:template>

</xsl:stylesheet>

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

1 Ответ

6 голосов
/ 13 июня 2011

Как указано в спецификации:

В отсутствие атрибута select инструкция xsl: apply-templates обрабатывает все дочерние элементы текущего узла, включая текстовые узлы.

apply-templates без выбора XPath, применяет шаблоны в соответствии с иерархией представления дерева XML, созданного процессором во время компиляции, если вы явно не управляете шаблонами (как вы делали для title и artist).

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

Так что, если вы пропустите совпадение с шаблоном для корня /, ваши шаблоны будут выполняться в любом случае, благодаря встроенному-in правила.

Я думаю, что порядок обработки должен быть таким:

  • Шаблон соответствует корню, а xsl:apply-templates говорит процессору применить шаблоны к catalog element (в том месте, где он вызывается).
  • Не найдено подходящих шаблонов для catalog, так что встроенное правило позволяет продолжать обработку в отношении других элементов-потомков (catalog) до тех пор, покаНайден новый шаблон с удачным совпадением с образцом (cd)

Встроенное правило работает за кулисами, и вы всегда должны думать, что ваше преобразование составлено вашими шаблонами, плюс несколько дополнительных скрытых (но работает) шаблоны:

<xsl:template match="*|/">
  <xsl:apply-templates />
</xsl:template>

<xsl:template match="text()|@*">
  <xsl:value-of select="."/>
</xsl:template>

<xsl:template match="processing-instruction()|comment()"/>

В вашем конкретном случае первый из трех приведенных выше шаблонов был ответственным за применениешаблоны для элементов cd.

Эти встроенные шаблоны переопределяются каждый раз, когда вы пишете явный шаблон.


Примеры

Вы можете получить то же самое, заменив:

<xsl:template match="cd">
    <p>
        <xsl:apply-templates select="title"/>
        <xsl:apply-templates select="artist"/>
    </p>
</xsl:template>

на:

<xsl:template match="country|company|price|year"/>

<xsl:template match="cd">
    <p>
        <xsl:apply-templates />
    </p>
</xsl:template>

О корне, в вашем случае, вы также можете получить то же самое, заменив:

<xsl:template match="/">
    <html>
        <body>
            <h2>My CD Collection</h2>
            <xsl:apply-templates/>
        </body>
    </html>
</xsl:template>

с

<xsl:template match="/catalog">
    <html>
        <body>
            <h2>My CD Collection</h2>
            <xsl:apply-templates/>
        </body>
    </html>
</xsl:template>

или все еще:

<xsl:template match="/">
    <html>
        <body>
            <h2>My CD Collection</h2>
            <xsl:apply-templates select="catalog"/>
        </body>
    </html>
</xsl:template>

или все еще:

<xsl:template match="catalog">
    <html>
        <body>
            <h2>My CD Collection</h2>
            <xsl:apply-templates />
        </body>
    </html>
</xsl:template>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...