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, George5 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.)
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:
<xsl:apply-templates>
stosuje szablony do dzieci węzła kontekstowego.Dopasowane węzły nie są "zwracane" w kroku 1; procesor XSLT znajduje szablon dla każdego z nich i stosuje go.
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.
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
-
<xsl:apply-templates />
spróbuje znaleźć szablon, który pasuje do bieżącego węzła i jego dzieci. - po tym, jak wszystkie dopasowane węzły zostaną zwrócone, procesor XSL wypowie te znaczniki zamykające (tj.
</body>
i</html>
) - 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>
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.
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.
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>
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