2012-09-10 11 views
23

Jestem nowym użytkownikiem xslt i stwierdziłem, że może on być łatwy lub złożony. Chcę wyjaśnić niektóre koncepcje. Co to jest poprzedzające rodzeństwo i co jest przodkiem, po przeszukaniu google, znalazłem wyjaśnienie przodka. a wykres z ich strony internetowej jest łatwiejszy do zrozumienia.Pojęcie XML XLST poprzedzające-rodzeństwo i przodek

Ale ja nadal nie rozumiem poprzedzający-rodzeństwo

<product> 
    <inventory> 
     <drink> 
      <lemonade> 
       <price>$2.50</price> 
       <amount>20</amount> 
      </lemonade> 
      <pop> 
       <price>$1.50</price> 
       <amount>10</amount> 
      </pop> 
     </drink> 
      <service> 
      <address /> 
      <phone /> 
      <delivery> City </delivery> 
      </service>  
     <snack> 
      <chips> 
       <price>$4.50</price> 
       <amount>60</amount> 
      </chips> 
     </snack> 
     <hotfood></hotfood> 
     <totalprice> $15</totleprice> 

    </inventory> 
</product> 

więc jak czytam ten poprzedzający-rodzeństwo :: pop/przodek :: inwentaryzacji/totalprice

przodek :: inwentaryzacji/totalprice = product \ inventory \ totalprice previous-sibling :: pop - Nie rozumiem tego jednego , a następnie jak czytać wszystko razem?

Dziękujemy

Odpowiedz

61

Poprzedzający-rodzeństwo :: oś

Poprzedzający-rodzeństwo :: oś jest osią nawigacji, która zawiera wszystkie powyższe elementy rodzeństwem elementu ostrości. Przez "rodzeństwo" rozumiemy inny element, który ma ten sam element nadrzędny względem elementu odniesienia. Przez "poprzedzający" rozumiemy węzeł, który występuje przed referencyjnym. Kolejność poprzedniej osi rodzeństwa jest odwrotną kolejnością dokumentów. Spójrz na ten dokument:

<fruit> 
    <banana> 
    <lady-finger-banana/> 
    </banana> 
    <apple/> 
    <pear/> 
    <kiwi/> 
</fruit> 

Jeśli węzeł celem jest gruszka, wówczas sekwencja poprzedzająca-rodzeństwo :: * jest ...

  1. jabłko
  2. banan

Uwaga: owoce, gruszki, banany i kiwi nie występują w sekwencji.

więc prawdziwe są następujące:

  1. poprzedzający-rodzeństwo :: * [1] jest jabłkiem
  2. poprzedzający-rodzeństwo :: * [2] banana
  3. count (preceding- rodzeństwa :: *) oznacza 2
  4. poprzedzających rodzeństwo :: jabłoni [1] jest również jabłko
  5. poprzedzających rodzeństwo :: bananów [1] banan
  6. poprzedzających rodzeństwo :: * [3] jest nieobecny lub emp Sekwencja ty

poprzedzający-rodzeństwo :: pop/przodek :: inwentaryzacji/totalprice Przykład

Musimy zmienić swój przykładowy dokument trochę do pożytkiem studiować tym przykładzie

<product> 
    <inventory> 
     <drink> 
      <lemonade> 
       <price>$2.50</price> 
       <amount>20</amount> 
      </lemonade> 
      <pop> 
       <price>$1.50</price> 
       <amount>10</amount> 
      </pop> 
      <focus-item /> 
     </drink> 
     <totalprice>$15</totalprice> 
    </inventory> 
</product> 

Niech nas powiedz, że fokus znajduje się na elemencie focus elementu. Aby ocenić ekspresję poprzedzający-rodzeństwo :: pop/przodek :: inwentaryzacji/totalprice następujące kroki

  1. poprzedzający rodzeństwo :: pop wybiera wszystkie powyższe elementy pop skupić-przedmiot. To ocenia sekwencję jednego węzła.
  2. Dla każdego elementu w sekwencji lewej (tylko jeden element pop to tak się dzieje), ustaw tę pozycję jako tymczasowy punkcie ostrości, a ocena ekspresji z prawej strony/operatora, który jest ...

    ancestor::inventory 
    

    Istnieje tylko jeden taki węzeł, który jest węzłem inwentarzowym przodków. Zatem pierwszy/operator ocenia sekwencję jednego węzła inwentaryzacji.

  3. Teraz oceniamy efekt łącznej ceny wyrażenia operandu i jego prawej strony. Dla każdego elementu w sekwencji lewej ręki (wystarczy tylko jeden węzeł ekwipunku), ustaw to jako tymczasowy element fokusu i oceń całkowitą cenę.

  4. totalprice to skrót od child :: totalprice. Na osi podrzędnej węzła tymczasowego fokusa znajduje się tylko jeden element ceny całkowitej, więc ostatecznym wynikiem jest sekwencja jednego węzła, który jest węzłem ceny całkowitej.

Zrozumienie przez Diagrams

Proszę spojrzeć na this page za ilustrację osiach.

Oto kopia diagramu tej strony dla poprzedzającego rodzeństwa ::. W nim węzłem referencyjnym jest Charlie, a węzeł na osi poprzedzającej-rodzeństwo :: jest zielony. Jest to jedyny taki węzeł. enter image description here

+0

bardzo jasne!wielkie dzięki: – olo

+0

@Sean: Jeśli mam fokus na elemencie focus elementu: 'parent :: *' dałoby mi '', 'ancestor :: *' dałoby mi '', '' i ' '. Czy to jest poprawne? Pozdrawiam, Peter (+1 za miłe wyjaśnienie) – Peter

+0

Tak, zgadza się. –

2

poprzedni-rodzeństwo pobiera wszystkie rodzeństwo elementów, które poprzedziły go na obecnym poziomie węzła. O ile nie określisz jednego lub więcej z tych poprzednich rodzeństwa z wyrażeniem xpath. Jeśli określisz konkretne poprzedzające-rodzeństwo za pomocą xpath, zawsze zaczyna się od 1 w nawiasach kwadratowych.

Przodek jest pierwszym pasującym przodkiem pasującym do wyrażenia. Powoduje przejście do drzewa węzłów w celu wyszukania pasującego wyrażenia na podstawie wskazanego miejsca. Więc jeśli byłeś w product/inventory/drink/pop lub just/pop, inwentarz przodka/totalprice szuka tylko pierwszego wystąpienia i powinien powrócić do wskaźnika tylko po to, by wskazać ten dopasowany przypadek, bo inaczej nic nie wskaże, a ty Nadal wskaże pop.

+0

Dziękuję bardzo za odpowiedź. czy mógłbym otrzymać trochę więcej przykładów? – olo

3

Osie przydatne do nawigacji po drzewie węzłów. Zależy więc od twojego problemu, jaki rodzaj osi jest przydatny.

Poniższy arkusz stylów ilustruje różnicę.

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:output method="xml" indent="yes"/> 

    <xsl:template match="snack"> 
     <xsl:variable name="siblings" select="ancestor::node()"/> 
     <debug> 
     <xsl:for-each select="preceding-sibling::node()"> 
       <sibling> 
         <xsl:value-of select="local-name()"/> 
       </sibling> 
     </xsl:for-each> 
     <xsl:for-each select="ancestor::node()"> 
       <ancestor> 
         <xsl:value-of select="local-name()"/> 
       </ancestor> 
     </xsl:for-each> 

     </debug> 
    </xsl:template> 

    <xsl:template match="*"> 
     <xsl:apply-templates select="*"/> 
    </xsl:template> 
</xsl:stylesheet> 
+0

ładny przykład +1 – Peter