Dla Grzegorza Enzo Dołęgowskiego za wpisanie moich notatek do komputera.
Przykłady są oparty na modelu danych i zachowania dla obiektowych baz danych.
K = {Osoba, Małżeństwo, Zameldowanie}
typ(Osoba) = [ PESEL : String; Imię : String; Nazwisko : String; Ojciec : Osoba; Matka : Osoba; Dzieci : {Osoba} ] typ(Małżeństwo) = [ Mąż : Osoba; Żona : Osoba; Data_zawarcia : Date; Data_ustania : Date; Dzieci : {Osoba} ] typ(Zameldowanie) = [ Obywatel : Osoba; Adres : [ Ulica : String; Nr_domu : String; Nr_miesz : String; Miejscowość : String; ] Od_kiedy : Date; Do_kiedy : Date; Rodzaj : String ]
select wyrażenie from ciąg deklaracji zmiennych zakresowych where warunek logiczny
Przy czym wyrażenie jest jednym z:
select [ Nazwisko : x.Nazwisko, Imię : x.Imię ] from x ∈ Osoba where x.Imię = 'Adolf';
select struct(Nazwisko : x.Nazwisko, Imię : x.Imię) from x in Osoba where x.Imię = 'Adolf';
select Nazwisko, Imię from Osoba where Imię = 'Adolf';
select x.Nazwisko, x.Imię from Osoba x where x.Imię = 'Adolf';
from → for x ∈ Osoba do where → if x.Imię = 'Adolf' then select → output [ Nazwisko : x.Nazwisko, Imię : x.Imię ]
select [ Nazwisko : x.Nazwisko, Rodzic : x.Imię, Dziecko : y.Imię ] from x ∈ Osoba, y ∈ x.Dzieci where x.Nazwisko = y.Nazwisko;
for x ∈ Osoba do for y ∈ x.Dzieci do if x.Nazwisko = y.Nazwisko then output [ Nazwisko : x.Nazwisko, Rodzic : x.Imię, Dziecko : y.Imię ]
select x.Nazwisko, x.Imię as Rodzic, y.Imię as Dziecko from Osoba as x, Osoba as y where x.Nazwisko = y.Nazwisko and y in x.Dzieci;
select [ Imię : x.Imię, Nazwisko : x.Nazwisko, Potomstwo : count(x.Dzieci) ] from x ∈ Osoba where count(x.Dzieci) > 5;
select x.Imię, x.Nazwisko, count(*) from Osoba x, Osoba y where x.PESEL = y.PESEL_matki or x.PESEL = y.PESEL_ojca group by x.PESEL, x.Imię, x.Nazwisko having count(*) > 5;
select x.Imię, x.Nazwisko, (select count(*) from Osoba y where x.PESEL = y.PESEL_ojca or x.PESEL = y.PESEL_matki) as Potomstwo from Osoba x where Potomstwo
select [ Imię : x.Imię, Nazwisko : x.Nazwisko, Wnuki : flatten(select y.Dzieci from y ∈ x.Dzieci ) ] from x ∈ Osoba;
select [ Nazwisko : y.Nazwisko, Rodzic : x.Imię, Jedynak : y.Imię ] from x ∈ Osoba, y ∈ x.Dzieci where count(x.Dzieci) = 1;
select [ Nazwisko : m.Mąż.Nazwisko, ImięŻony : m.Żona.Imię, ImięMęża : m.Mąż.Imię ] from m ∈ Małżeństwo where Data_zawarcia > #16.03.2006#;
Wyrażenia scieżkowe są:
Wyrażenia ścieżkowe z wyrażeniami regularnymi zawsze są zbiorowe:
Krok ścieżki | Znaczenie |
---|---|
_ | Dowolna krawędź grafu |
(x) | 0 albo 1 wystąpienie ścieżki x |
(x)* | Dowolna liczba (również 0) wystąpień ścieżki x |
(x)+ | Dowolna dodatnia liczba wystąpień ścieżki x |
(x | y) | Jedno wystąpienie ścieżki x albo jedno wystąpienie ścieżki y |
select [ Imię : z.Imię, Nazwisko : z.Nazwisko ] from x ∈ (select y from y ∈ Osoba where y.Imię = 'Krzysztof and y.Nazwisko = 'Stencel'), z ∈ x._*.(Ojciec|Matka)
select [ Imię : z.Imię, Nazwisko : z.Nazwisko ] from x ∈ (select y from y ∈ Osoba where y.Imię = 'Krzysztof and y.Nazwisko = 'Stencel z ∈ x.(Ojciec|Matka)+
Na zmiennej ścieżkowej możemy zapamiętać ścieżkę, która doprowadziła do przetwarzanego obiektu:
(ścieżka)@Z
Do zmiennej odwołujemy się poprzez @Z. Ścieżki i nazwy pól są obywatelami I kategorii.
select [ Imię : y.Imię, Nazwisko : y.Nazwisko, Pokrewieństwo : @P ] from x ∈ Osoba, y ∈ x.((Ojciec|Matka)+)@P where x.Imię = 'Krzysztof' and x.Nazwisko = 'Stencel';
select [ Imię : z.Imię, Nazwisko : z.Nazwisko, @P: u.Imię ] fromz ∈ Osoba, u ∈ z.(Ojciec|Matka)@P;
select [ Imię : z.Imię, Nazwisko : z.Nazwisko, pokrewieństwo : @P, TenSamPoziomPokrewieństwaUKorbsdaja : y.@P.Imię ] from x ∈ Osoba, z ∈ x.((Ojciec|Matka)*)@P, y ∈ Osoba where x.Imię = 'Krzysztof' and x.Nazwisko = 'Stencel' and y.Imię = 'Marcin' and y.Nazwisko = 'Korbsday';
Rozpatrujemy tylko ścieżki bez cyklu, a dokładniej bez powtórzeń węzłów. Co najwyżej jeden węzeł może wystąpić dwa razy i wtedy jest on także węzłem ostatnim. Wyrażenia ścieżkowe ewaluuje się do zbioru ścieżek.
Ścieżką nazwiemy ciąg (w0, l1, w1, l2, w2, ..., ln-1, wn-1, ln, wn). Dla takiej ścieżki zmienna ścieżkowa ma wartość:
@P = l1, l2, ..., ln
select [ Imię : x.Imię, Nazwisko : x.Nazwisko, Wnuki : flatten(select y.Dzieci from y ∈ x.Dzieci) ] from x ∈ Osoba;
Przyjrzymy się wyrażeniu:
flatten(select y.Dzieci from y ∈ x.Dzieci)
i typom jego podwyrażeń:
typ(y.Dzieci) = {Osoba} typ(select y.Dzieci from y ∈ x.Dzieci) = {{Osoba}} typ(flatten(select y.Dzieci from y ∈ x.Dzieci)) = {Osoba}
W językach „strukturalnych”, gdy nie wolno korzystać ze zbiorowych wyrażeń ścieżkowych konieczne jest flatten i podzapytanie select. W językach „semistrukturalnych” za pomocą zbiorowych wyrażeń ścieżkowych możemy napisać to zapytanie znacznie prościej.
select [ Imię : x.Imię, Nazwisko : x.Nazwisko, Wnuki : x.Dzieci.Dzieci ] from x ∈ Osoba;
Grafy bez typów, np. OEM (Object Exchange Model) to zbiór krotek (oid, typ, wartość). Jeśli typ węzła jest złożony, to mogą z niego wychodzić krawędzie skierowane do innych węzłów (dowolnych). Tu najlepiej pasują te konstrukcje ścieżkowe, ponieważ chodzimy po grafie.
Wierzchołki w grafie są:
select x from DB.Osoba x where exists y in x.Dziecko : y.Imię = 'Józef';
select wnuk : x from DB.Osoba.Dziecko.Dziecko x;
select wnuki : (select y from x.Dziecko y) from DB.Osoba.Dziecko x;
select potomki : (select y from x(.Dziecko)* y) from DB.Osoba x;
select osobaipotomki : [ x, potomki : (select y from x(.Dziecko)* y) ] from DB.Osoba x;
select małżonek : [ rola : @L, kto : x.Nazwisko ] from DB.Małżeństwo._@L x where @L = 'Mąż' or @L = 'Żona';
select małżonek : [ rola : @L, kto : x.Nazwisko ] from DB.Małżeństwo. _@L x where @L <> 'Ksiądz' and count(x.Nazwisko) > 0;
XML należy uważać za sposób zapisu i transmisji danych. XML jest dobrym sposobem zapisu danych seminstrukturalnych.
<!ELEMENT USC (Osoba+)> <!ELEMENT Osoba (PESEL, Imię, Nazwisko, Zameldowanie*, Dzieci?)> <!ELEMENT PESEL (#PCDATA)> <!ELEMENT Imię (#PCDATA)> <!ELEMENT Nazwisko (#PCDATA)> <!ELEMENT Dzieci (Osoba+)> <!ELEMENT Zameldowanie (Adres, Data_od, Data_do?)> <!ELEMENT Data_od (#PCDATA)> <!ELEMENT Data_do (#PCDATA)> <!ELEMENT Adres (Miejscowość, Ulica?, Nr_domu, Nr_mieszkania?)> <!ELEMENT Miejscowość (#PCDATA)> <!ELEMENT Ulica (#PCDATA)> <!ELEMENT Nr_domu (#PCDATA)> <!ELEMENT Nr_mieszkania (#PCDATA)>
<?xml version="1.0" encoding="windows-1250" ?> <USC> <Osoba> <PESEL>71071287347</PESEL> <Imię>Krzysztof</Imię> <Nazwisko>Stencel</Nazwisko> <Dzieci> <Osoba> <PESEL>98050342344</PESEL> <Imię>Julia</Imię> <Nazwisko>Stencel</Nazwisko> </Osoba> <Osoba> <PESEL>00022045455</PESEL> <Imię>Klaudia</Imię> <Nazwisko>Stencel</Nazwisko> </Osoba> <Osoba> <PESEL>02090475747</PESEL> <Imię>Natalia</Imię> <Imię>Kornelia</Imię> <Nazwisko>Stencel</Nazwisko> </Osoba> </Dzieci> </Osoba> </USC>
where oddzielone przecinkami warunki i deklaracje zmiennych zakresowych construct wynik
where <Osoba> <PESEL>$P</PESEL> <Dzieci>$y</Dzieci> </Osoba> in 'abc.xml' construct <result>$P</result>
</>
zamyka ostatni znacznik):where <Osoba></> element_as $O in 'abc.xml' construct $O
where <Osoba> <PESEL>$P</PESEL> <Imię>$I</> <Nazwisko>$N</> </> in 'abc.xml', $I = $N construct <result> $P</>
where <Osoba> <Nazwisko>$N</> <Dzieci>$D</> </> in 'abc.xml', <Osoba> <Nazwisko>$M</> </> in $D, $M != $N construct <wynik> <Rodzic>$N</> <Dziecko>$M</> </>
where <Nazwisko>$N</> in 'abc.xml' construct <Lista> <Nazwisko>$N</> where <Osoba> <PESEL>$P</> <Nazwisko>$M</> </> element_as $O in 'abc.xml', $N = $M construct $O </>
where <$P></> in 'abc.xml' construct <Znacznik>$P</>
where <Osoba> <(Dzieci.Osoba)+></> element_as $O </> in 'abc.xml' construct <Potomek>$O</>
where <(Dzieci.Osoba)+.(Miejscowość|Ulica)>$A</> in 'abc.xml' construct <Adres>$A</>
where <Osoba> <Dzieci> <Osoba[$I]>$O</> </> </> construct <Dziecko> <Nr>$I</> <Osoba>$O</> </>
XSLT też jest językiem zapytań, choć trochę nietypowym. XSLT odpowiada gramatyce atrybutywnej za akcjami. Arkusz stylów XSLT steruje zejściami rekurencyjnymi w głąb przetwarzanego dokumentu.
<?xml version="1.0" encoding="windows-1250" ?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:html="http://www.w3.org/TR/REC-html40"> <xsl:template match="/"> <html:html> <html:head> <html:title>Lista rodów</html:title> </html:head> <html:body> <xsl:apply-templates/> </html:body> </html:html> </xsl:template> <xsl:template match="/Osoba"> <html:h1>Ród: <xsl:apply-templates select="Nazwisko"/></html:h1> <html:ul> <xsl:call-template name="wydruk-Osoby"/> </html:ul> </xsl:template> <xsl:template match="Osoba" name="wydruk-Osoby"> <html:li> Nazwisko: <xsl:apply-templates select="Nazwisko"/><html:br/> Imię: <xsl:apply-templates select="Imię"/> <xsl:if test="Dzieci"> <html:ul> <xsl:apply-templates select="Dzieci/Osoba"/> </html:ul> </xsl:if> </html:li> </xsl:template> <xsl:template match="Nazwisko"> <html:b> <xsl:value-of select="."/></html:b> </xsl:template> <xsl:template match="Imię"> <html:b> <xsl:value-of select="."/></html:b> </xsl:template> </xsl:stylesheet>