XSLT apply-pytanie o szablon

Jestem zdezorientowany co do instrukcji XSLT apply-template. Na przykład tutaj, w w3school.

Http://www.w3schools.com/xsl/xsl_apply_templates.asp

Dla wypowiedzi,

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

Moje konfuzje to:

(1) Jaka jest funkcja <xsl:apply-templates/>? Nie zawiera żadnego konkretnego szablonu do wywołania. Myślę, że dopasuje (zwróci) wszystkie bezpośrednio potomkinie bieżącego elementu (nie - bezpośrednie dziecko bieżącego węzła nie zostanie zwrócone, bieżący węzeł jest węzłem głównym), nie jestem pewien czy mam rację?

(2) gdy wszystkie dopasowane węzły zostaną zwrócone w (1), Jaki będzie następny krok procesora XSLT?

(3) w tej specyfikacji węzeł root jest katalogiem lub innym wyższym poziomem roota? i dlaczego?

Z góry dzięki, George
 21
Author: George2, 2009-12-29

5 answers

Niektóre rzeczy, które ułatwią zrozumienie odpowiedzi:

Po pierwsze i najważniejsze, węzły i elementy to nie to samo . Elementy są węzłami, ale węzły niekoniecznie są elementami. Często spotykasz ludzi używających tych terminów zamiennie. W XML istnieją cztery rodzaje węzłów: elementy, węzły tekstowe, instrukcje przetwarzania i komentarze. (Atrybuty nie są tak naprawdę węzłami, do których dojdę za chwilę.)

W XSLT, korzeń XML dokument nie jest jego nadrzędnym elementem; główny element jest abstrakcją, która tak naprawdę nie istnieje. Element najwyższego poziomu jest potomkiem korzenia. Na przykład, oto dobrze uformowany dokument XML, którego root ma pięć węzłów potomnych, w tym element najwyższego poziomu: {]}

<?xml-stylesheet href="mystyle.css" type="text/css"?>
<!-- this is a perfectly legitimate XML document -->
<top_level_element/>
Pięć? Wygląda na to, że są tylko trzy. Myślę, że pozwolę ci dowiedzieć się, czym są pozostałe dwie. Podpowiedź: w tym przykładzie może być siedem węzłów.

Wyrażenie XPath / znajduje główny dokument, a nie element najwyższego poziomu. W powyższym przypadku, aby znaleźć element najwyższego poziomu, należy użyć /top_level_element lub /*. (Zawsze można użyć /*, aby znaleźć element najwyższego poziomu, ponieważ główny dokument musi mieć element potomny jednego elementu.)

Więc uzbrojeni w tę wiedzę, spójrzmy na to, co robi. Zasadniczo wykonuje dwuetapowy proces: po pierwsze, buduje zestaw węzłów. Następnie, i dla każdego z nich, znajduje pasujący szablon (spośród szablonów w XSLT plik) i stosuje do niego szablon. Jak zauważyłeś w jednym z twoich komentarzy, jest koncepcyjnie bardzo podobna do pętli.

Atrybut select jest używany w pierwszym kroku. Zapewnia wyrażenie XPath, które jest używane do budowania zestawu węzłów, do którego będzie stosować szablony. Jeśli nie podano atrybutu select, budowana przez niego lista jest potomkami węzła kontekstowego. ("Węzeł kontekstowy" to węzeł, do którego stosowany jest bieżący szablon.)

Atrybut match na elementach template jest używany w drugim kroku. Procesor arkuszy stylów znajduje Wszystkie szablony, których atrybut match pasuje do węzła, do którego próbuje zastosować szablony. Jeśli znajdzie więcej niż jeden, wybiera najbardziej konkretny, jaki może, np. biorąc pod uwagę te szablony: {]}

<xsl:template match="*"/>
<xsl:template match="foo"/>
<xsl:template match="foo[bar]"/>

Element foo z elementem potomnym będzie dopasowany przez trzeci, element foo Bez bar będzie dopasowany przez drugi, a element baz będzie dopasowany przez pierwszy. (Rzeczywista metoda to, czego używa XSLT jest zdefiniowane tutaj; w praktyce używam XSLT od prawie dekady i nigdy nie musiałem dokładnie wiedzieć, jak to działa, choć jest to interesujące.)

Jeśli nie znajdzie dopasowania, użyje wbudowanego domyślnego szablonu dla typu węzła-zasadniczo można założyć, że każda transformata XSLT domyślnie zawiera te szablony:

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

<xsl:template match="text()">
    <xsl:copy/>
</xsl:template>

<xsl:template match="processing-instruction() | comment() | @*"/>
[25]} uzbrojony w całą tę wiedzę, możesz teraz zrozumieć tożsamość transformacja:
<xsl:template match="node() | @*">
    <xsl:copy>
        <xsl:apply-templates select="node() | @*"/>
    </xsl:copy>
</xsl:template>

, który pasuje do dowolnego węzła lub atrybutu (zauważ, że atrybuty nie są węzłami, dlatego jest potrzebna @*), kopiuje go, a następnie stosuje szablony do wszystkich jego węzłów podrzędnych i atrybutów. (Tylko główny dokument i elementy będą miały węzły podrzędne, a tylko elementy będą miały atrybuty.) Ponieważ jest to jedyny szablon w transformacji i pasuje do wszystkich węzłów i atrybutów, stosuje się do wszystkich węzłów i atrybutów potomnych. Kopiuje więc wszystko w drzewo źródłowe do drzewa wyjściowego.

Jeśli dodasz ten szablon do transformacji identify:

<xsl:template match="foo"/>

Masz teraz transformację, która kopiuje każdy węzeł w drzewie źródłowym z wyjątkiem foo elements - ten drugi szablon pasuje do elementów foo (pierwszy też, ale ponieważ atrybut match drugiego jest bardziej specyficzny, to XSLT wybiera) i nic z nimi nie robi.

Biorąc to wszystko, odpowiedzi na swoje konkretne pytania:

  1. <xsl:apply-templates> stosuje szablony do dzieci węzła kontekstowego.

  2. Dopasowane węzły nie są "zwracane" w kroku 1; procesor XSLT znajduje szablon dla każdego z nich i stosuje go.

  3. W tym przykładzie węzeł kontekstowy jest głównym węzłem dokumentu, abstrakcyjnym węzłem, którego potomkami są elementy najwyższego poziomu oraz wszelkie komentarze lub instrukcje przetwarzania znajdujące się poza nim.

 48
Author: Robert Rossney,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-12-29 21:08:42
  1. <xsl:apply-templates /> spróbuje znaleźć szablon, który pasuje do bieżącego węzła i jego dzieci.
  2. po tym, jak wszystkie dopasowane węzły zostaną zwrócone, procesor XSL wypowie te znaczniki zamykające (tj. </body> i </html>)
  3. jest węzeł główny, tuż przed katalogiem, dopasowany przez "/"

EDIT: przykład do wyjaśnienia 1.; rozważ dostarczoną próbkę :

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

    <xsl:template match="/">
      Here we're at "root" node, just before "catalog" element.<br />
      Let's enumerate this child nodes:
      <ul>
      <xsl:for-each select="*">
          <li><xsl:value-of select="name()" /></li>
      </xsl:for-each>
      </ul>
      <!-- Now, process "catalog" and ALL his child nodes -->
      <xsl:apply-templates/>  
    </xsl:template>

    <xsl:template match="cd">
      <p>
        <!-- Find a template ONLY for title element -->
        <xsl:apply-templates select="title"/> 
        <xsl:apply-templates select="artist"/>
      </p>
    </xsl:template>
</xsl:stylesheet>
 3
Author: Rubens Farias,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-12-29 18:53:57

Xsl: apply-templates kieruje silnik XSLT, aby dopasować bieżące podnody dokumentu źródłowego do szablonów arkuszy stylów do dalszego przetwarzania.

 1
Author: Ignacio Vazquez-Abrams,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-12-29 09:57:16

1) <xsl:apply-templates/> wywołuje przejścia przez wszystkie podnody (dzieci) i wywołuje dopasowany szablon, jeśli istnieje.

2) po dopasowaniu wszystkich węzłów następujące linie są wyjściowe, które w tym przypadku są

</body> 
</html>

3) w przykładowym katalogu znajduje się węzeł główny.

 1
Author: Rashmi Pandit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-12-29 10:03:52
  • Element XML ma dzieci lub atrybuty. W XML poniżej element book posiada child:: author (krótko author) oraz atrybut:: first (krótko @ first)

    <?xml version="1.0" encoding="UTF-8"?> <book> <author first="tom">Smith</author> </book>

  • Xsl: apply-templates oznacza execute templates dla wszystkich dzieci dopasowanego węzła, więc dla poniższego szablonu, execute template for author , ale nie dla @ first .

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

  • text() node Smith jest potomkiem elementu autor, więc xsl:apply-templates wywoła szablon dla text () node:

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

 0
Author: mg_kedzie,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-27 18:49:20