Die Präsentation wird geladen. Bitte warten

Die Präsentation wird geladen. Bitte warten

1 XQuery Informationssysteme, 14.06.2007 Vortragender: Michael Schmidt.

Ähnliche Präsentationen


Präsentation zum Thema: "1 XQuery Informationssysteme, 14.06.2007 Vortragender: Michael Schmidt."—  Präsentation transkript:

1 1 XQuery Informationssysteme, 14.06.2007 Vortragender: Michael Schmidt

2 2 XPath (Wiederholung) Anfragesprache auf XML XPath-Expressions selektieren Knoten des Eingabe-Dokuments bib book title author /bib//title

3 3 XPath (Wiederholung) Path Steps: axis::nodetest Axen: child, descendant, ancestor, following, following-sibling,... Node-tests: Tag, *, node(), text() Absolute Pfade: /step/step/… Relative Pfade: step/step/...

4 4 XQuery SQL für XML W3C Recommendation Funktionale Programmiersprache, Turing-vollständig XQueries enthalten XPath Ausdrücke Ergebnis einer XQuery: wohlgeformte XML- Dokumente (XPath: Menge von Knoten) Keine Datenmanipulationssprache (z.B. keine Updates)

5 5 Node-Construction und Konstanten { " Hello World " } XQuery Hello World Ergebnis " Hello World " XQuery "Hello World" Ergebnis

6 6 Dokument-Zugriff { doc( " bookstore.xml " )/bib/book[price>30] } T1 A1 50 T2 A2 20 T3 A3 bookstore.xml T1 A1 50 Ergebnis XQuery

7 7 Sequenz { ( doc( " bookstore.xml " )/bib/article/title, doc( " bookstore.xml " )/bib/book/title ) } T3 T1 T2 T1 A1 50 T2 A2 20 T3 A3 bookstore.xml Ergebnis XQuery Ordnung bleibt erhalten!

8 8 FR-Expression { for $book in doc( " bookstore.xml " )//book return $book/title } T1 A1 50 T2 A2 20 T3 A3 bookstore.xml T1 T2 Ergebnis XQuery

9 9 FWR-Expressions { for $book in doc( " bookstore.xml " )//book where $book/price>30 return { $book/title/text() } T1 A1 50 T2 A2 20 T3 A3 bookstore.xml T1 Ergebnis Konstruktion von Knoten, die im Dokument nicht vorkommen XQuery

10 10 FLWR-Expressions T1 A1 50 T2 A2 20 T3 A3 bookstore.xml { for $book in doc("bookstore.xml")//book let $booktitle := { $book/title/text() } where ($book/price>30) return $booktitle } T1 Ergebnis XQuery

11 11 FLWOR-Expressions { for $book in doc( " bookstore.xml " )//book let $booktitle := $book/title where ($book/price>10) order by $booktitle/text() descending return { $booktitle/text() } } T1 A1 50 T2 A2 20 T3 A3 bookstore.xml T2 T1 Ergebnis XQuery

12 12 Where-Expressions Konnektive and, or, fn:not T1 A1 50 T2 A2 20 T3 A3 bookstore.xml { for $book in doc( " bookstore.xml " )//book where ($book/price>10 and fn:not($book/author/text()= " A1 " )) return $book/title } T2 Ergebnis XQuery

13 13 Some-Expressions bookstore.xml { for $book in doc( " bookstore.xml " )//book where (some $a in $book/author satisfies $a/text()= " A2 " ) return $book/title } Ergebnis XQuery T1 A1 A2 T2 A3 A4 T1

14 14 For vs let-Expressions { for $x in (1 to 5) return {$x} } { let $x:=(1 to 5) return {$x} } 1 2 3 4 5 XQuery 1 XQuery 2 Ergebnis Iteration keine Iteration 1 2 3 4 5 Ergebnis

15 15 If-then-else Expressions { for $book in doc("bookstore.xml")//book return if (fn:exists($book/price)) then { $book/title } else { $book/title } } XQuery bookstore.xml T1 A1 T2 A2 30 T1 T2 Ergebnis

16 16 Vordefinierte Funktionen Zahlreiche built-in Functions: Boolean: fn:exists(), fn:empty() … String Manipulation: fn:concat(), fn:uppercase() … String Tests: fn:contains(), fn:starts-with() … Sequenzen: fn:exactly-one(), fn:distinct-values() … Mathematisch: fn:floor(), fn:round(), fn:abs() … …

17 17 Vordefinierte Funktionen { for $book in doc( " bookstore.xml " )//book where (fn:exists($book/price) and fn:contains($book/author, " A " )) return $book/title } XQuery T1 A1 50 T2 A2 20 T3 A3 bookstore.xml T1 T2 Ergebnis

18 18 XQuery Joins Vergleich unterschiedlicher Teile des Eingabe- Dokuments Auch Joins zwischen verschiedenen Dokumenten möglich Im Gegensatz zu SQL-Joins, oftmals nicht leicht zu erkennen, da keine eigene Syntax (kein JOIN-Keyword) Optimierung der Auswertung von Joins durch herkömmliche und XML-spezifische Methoden

19 19 XQuery Joins { for $bib in doc( " bookstore.xml " )/bib return for $book in $bib/book return for $article in $bib/article where $book/author=$article/author return { $book/title, $article/title} } XQuery bib book titleauthor T1A1 book titleauthor T2A2 article titleauthor T3A3 article titleauthor T4A1 $book $article T1 T4 Ergebnis

20 20 XQuery Joins { for $a in doc("www.amazon.com/review.xml")//book for $b in doc("www.bn.com/bib.xml")//entry where $a/isbn = $b/isbn return { $b/title } { $a/price/text() } { $b/price/text() } } XQuery Join über zwei Dokumente

21 21 Aggregatfunktionen fn:min(), fn:max(), fn:count(), fn:sum(), fn:avg() { for $book in doc( " bookstore.xml " )//book return { ($book/title, { fn:count($book/author) } ) } XQuery bookstore.xml T1 A1 A2 T2 A3 T1 2 T2 1 Ergebnis

22 22 Aggregatfunktionen { for $o in fn:distinct-values(doc("adressen.xml")//ort) let $ort:=doc("adressen.xml")//ort[self::node()=$o] where fn:count($ort)>=2 order by $o return {($ort[1]/name,$ort[1]/plz)} {count($ort)} } Beispiel: Gegeben Adressdatenbank, berechne Orte und Zahl der Adressen für Orte mit mind. 2 Adressen adressen.xml SB 66121 S1 SB 66121 S2 … Ergebnis SB66121, NK66538, …

23 23 Datentransformation XML: Generalisierung von HTML XQuery ermöglicht Anfragen auf XML- Dokumente und direkte Ausgabe von HTML XML und XQuery in Web-Szenarien gut geeignet

24 24 Datentransformation T1 A1 50 T2 A2 20 T3 A3 bookstore.xml Angebot Buchliste { for $book in doc("bookstore.xml")//book return {$book/title/text()} {$book/author/text()} } XQuery

25 25 Datentransformation Angebot Buchliste T1 A1 T2 A2 Ergebnis

26 26 Vielfalt an Konstrukten FLWOR – Expressions Aggregationen Typkonversionen (nicht besprochen) Gleichheit von Knoten (Benutzerdefinierte) Funktionen Sehr komplex, effiziente Auswertung von XQuery noch immer ein aktives Forschungsgebiet

27 27 XQ – ein XQuery Fragment query ::= Ɛ | query | query query | var | var/axis::v | for var in var/axis::v return query | if cond then query else query cond ::= var = var | var = | true | some var in var/axis::v satisfies cond | cond and cond | cond or cond | not cond Syntax Composition-free XQ

28 28 Composition-free XQuery book bib book { let $x := { for $book in /bib/book return { $book } } for $b in $x/booklist/b return $b/* } XQuery

29 29 Composition-free XQuery book bib book booklist book b b $x $book { let $x := { for $book in /bib/book return { $book } } for $b in $x/booklist/b return $b/* } neu konstruiert XQuery

30 30 Composition-free XQuery book bib book booklist book b b $x book books book $book $b { let $x := { for $book in /bib/book return { $book } } for $b in $x/booklist/b return $b/* } XQuery

31 31 Composition-free XQuery in der Praxis: viele XQuery Anfragen mit Komposition können in äquivalente XQ-Anfragen umgeschrieben werden { let $x := { for $book in /bib/book return { $book } } for $b in $x/booklist/b return $b/* } { for $book in /bib/book return $book } XQuery XQ query

32 32 Eigenschaft von XQ niedrigere Komplexität in der Auswertung Variablen binden immer an einen Knoten im Eingabebaum { for $x in //x return for $y in $x//y return $y } x x yy $x r Ergebnis XQ expression

33 33 Eigenschaft von XQ niedrigere Komplexität in der Auswertung Variablen binden immer an einen Knoten im Eingabebaum x x yy $x $y r Ergebnis { for $x in //x return for $y in $x//y return $y } XQ expression

34 34 Eigenschaft von XQ niedrigere Komplexität in der Auswertung Variablen binden immer an einen Knoten im Eingabebaum x x yy $x $y r Ergebnis { for $x in //x return for $y in $x//y return $y } XQ expression

35 35 Eigenschaft von XQ niedrigere Komplexität in der Auswertung Variablen binden immer an einen Knoten im Eingabebaum x x yy $x r Ergebnis { for $x in //x return for $y in $x//y return $y } XQ expression

36 36 Eigenschaft von XQ niedrigere Komplexität in der Auswertung Variablen binden immer an einen Knoten im Eingabebaum x x yy $y r $x Ergebnis { for $x in //x return for $y in $x//y return $y } XQ expression

37 37 Eigenschaft von XQ niedrigere Komplexität in der Auswertung Variablen binden immer an einen Knoten im Eingabebaum x x yy r $x $y Ergebnis { for $x in //x return for $y in $x//y return $y } XQ expression

38 38 XQ formale Semantik k: Anzahl gebundener Variablen e: derzeitiges environment (Variablenbindung) false als leere Liste Ergebnis: Liste von Knoten

39 39 XQ formale Semantik

40 40 XQ formale Semantik

41 41 XQ Evaluierung [[ { $x 2 $x 1 } ]] 2 (, ) = [ [[$x 2 $x 1 ]] 2 (, ) ] = [ [[$x 2 ]] 2 (, ) [[$x 1 ]] 2 (, ) ] = [ ]

42 42 XQ Evaluierung { for $book in //book return if (some $author in $book/author satisfies $author/text()=A1) then $book else () } bookstore.xml T1 A1 T2 A2 XQuery

43 43 XQ Evaluierung [[ { for $book in //book return if (some $author in $book/author satisfies $author/text()=A1) then $book else ()} ]] 0 ()

44 44 XQ Evaluierung [[ { for $book in //book return if (some $author in $book/author satisfies $author/text()=A1) then $book else ()} ]] 0 () [[for $book in //book return if (some $author in $book/author satisfies $author/text()=A1) then $book else ()]] 0 ()

45 45 XQ Evaluierung [[ { for $book in //book return if (some $author in $book/author satisfies $author/text()=A1) then $book else ()} ]] 0 () [[for $book in //book return if (some $author in $book/author satisfies $author/text()=A1) then $book else ()]] 0 () l=[[//book]] 0 () = [ A1 T1, A2 T2 ]

46 46 XQ Evaluierung [[ { for $book in //book return if (some $author in $book/author satisfies $author/text()=A1) then $book else ()} ]] 0 () [[for $book in //book return if (some $author in $book/author satisfies $author/text()=A1) then $book else ()]] 0 () l=[[//book]] 0 () = [ A1 T1, A2 T2 ] [[if (some …)]] 1 (l 1 ) + [[if (some …)]] 1 (l 2 )

47 47 XQ Evaluierung [[if (some $author in $book/author satisfies $author/text()=A1) then $book else ()]] 1 ( A1 T1 ) [[ { for $book in //book return if (some $author in $book/author satisfies $author/text()=A1) then $book else ()} ]] 0 () [[for $book in //book return if (some $author in $book/author satisfies $author/text()=A1) then $book else ()]] 0 () l=[[//book]] 0 () = [ A1 T1, A2 T2 ] [[if (some …)]] 1 (l 1 ) + [[if (some …)]] 1 (l 2 )

48 48 XQ Evaluierung [[for $author in $book/author return $author/text()=A1]] 1 ( A1 T1 ) [[if (some $author in $book/author satisfies $author/text()=A1) then $book else ()]] 1 ( A1 T1 ) [[ { for $book in //book return if (some $author in $book/author satisfies $author/text()=A1) then $book else ()} ]] 0 () [[for $book in //book return if (some $author in $book/author satisfies $author/text()=A1) then $book else ()]] 0 () l=[[//book]] 0 () = [ A1 T1, A2 T2 ] [[if (some …)]] 1 (l 1 ) + [[if (some …)]] 1 (l 2 )

49 49 XQ Evaluierung l =[[$book/author]] 1 ( A1 T1 ) = [ A1 ] [[for $author in $book/author return $author/text()=A1]] 1 ( A1 T1 ) [[ { for $book in //book return if (some $author in $book/author satisfies $author/text()=A1) then $book else ()} ]] 0 () [[for $book in //book return if (some $author in $book/author satisfies $author/text()=A1) then $book else ()]] 0 () l=[[//book]] 0 () = [ A1 T1, A2 T2 ] [[if (some …)]] 1 (l 2 ) + [[if (some …)]] 1 (l 1 ) [[if (some $author in $book/author satisfies $author/text()=A1) then $book else ()]] 1 ( A1 T1 ) [[$author/text()=A1]] 2 ( …, A1 )

50 50 XQ Evaluierung [[$author/text()=A1]] 2 ( …, A1 ) [ ] l =[[$book/author]] 1 ( A1 T1 ) = [ A1 ] [[for $author in $book/author return $author/text()=A1]] 1 ( A1 T1 ) [[if (some $author in $book/author satisfies $author/text()=A1) then $book else ()]] 1 ( A1 T1 ) [[ { for $book in //book return if (some $author in $book/author satisfies $author/text()=A1) then $book else ()} ]] 0 () [[for $book in //book return if (some $author in $book/author satisfies $author/text()=A1) then $book else ()]] 0 () l=[[//book]] 0 () = [ A1 T1, A2 T2 ] [[if (some …)]] 1 (l 1 ) + [[if (some …)]] 1 (l 2 ) [[$author/text()]] 2 (…) [A1] [[A1]] 2 (…) [A1]

51 51 XQ Evaluierung [[$author/text()=A1]] 2 ( …, A1 ) [ ] l =[[$book/author]] 1 ( A1 T1 ) = [ A1 ] [[for $author in $book/author return $author/text()=A1]] 1 ( A1 T1 ) [ ] [[if (some $author in $book/author satisfies $author/text()=A1) then $book else ()]] 1 ( A1 T1 ) [[ { for $book in //book return if (some $author in $book/author satisfies $author/text()=A1) then $book else ()} ]] 0 () [[for $book in //book return if (some $author in $book/author satisfies $author/text()=A1) then $book else ()]] 0 () l=[[//book]] 0 () = [ A1 T1, A2 T2 ] [[if (some …)]] 1 (l 1 ) + [[if (some …)]] 1 (l 2 )

52 52 XQ Evaluierung [[$book]] 1 ( A1 T1 ) [ A1 T1 ] [[$author/text()=A1]] 2 ( …, A1 ) [ ] l =[[$book/author]] 1 ( A1 T1 ) = [ A1 ] [[for $author in $book/author return $author/text()=A1]] 1 ( A1 T1 ) [ ] [[if (some $author in $book/author satisfies $author/text()=A1) then $book else ()]] 1 ( A1 T1 ) [ A1 T1 ] [[ { for $book in //book return if (some $author in $book/author satisfies $author/text()=A1) then $book else ()} ]] 0 () [[for $book in //book return if (some $author in $book/author satisfies $author/text()=A1) then $book else ()]] 0 () l=[[//book]] 0 () = [ A1 T1, A2 T2 ] [[if (some …)]] 1 (l 1 ) + [[if (some …)]] 1 (l 2 ) [ A1 T1 ] +

53 53 XQ Evaluierung [[ { for $book in //book return if (some $author in $book/author satisfies $author/text()=A1) then $book else ()} ]] 0 () [[for $book in //book return if (some $author in $book/author satisfies $author/text()=A1) then $book else ()]] 0 () l=[[//book]] 0 () = [ A1 T1, A2 T2 ] [[if (some …)]] 1 (l 1 ) + [[if (some …)]] 1 (l 2 ) [ A1 T1 ] + [[if (some $author in $book/author satisfies $author/text()=A1) then $book else ()]] 1 ( A2 T2 )

54 54 XQ Evaluierung [[ { for $book in //book return if (some $author in $book/author satisfies $author/text()=A1) then $book else ()} ]] 0 () [[for $book in //book return if (some $author in $book/author satisfies $author/text()=A1) then $book else ()]] 0 () l=[[//book]] 0 ()= [ A1 T1, A2 T2 ] [[if (some …)]] 1 (l 0 ) + [[if (some …)]] 1 (l 1 ) [ A1 T1 ] + [[if (some $author in $book/author satisfies $author/text()=A1) then $book else ()]] 1 ( A2 T2 ) [[for $author in $book/author return $author/text()=A1]] 1 ( A2 T2 )

55 55 XQ Evaluierung [[ { for $book in //book return if (some $author in $book/author satisfies $author/text()=A1) then $book else ()} ]] 0 () [[for $book in //book return if (some $author in $book/author satisfies $author/text()=A1) then $book else ()]] 0 () l=[[//book]] 0 ()= [ A1 T1, A2 T2 ] [[if (some …)]] 1 (l 1 ) + [[if (some …)]] 1 (l 2 ) [ A1 T1 ] + [[if (some $author in $book/author satisfies $author/text()=A1) then $book else ()]] 1 ( A2 T2 ) [[for $author in $book/author return $author/text()=A1]] 1 ( A2 T2 ) l =[[$book/author]] 1 ( A2 T2 ) = [ A2 ] [[$author/text()=A1]] 2 ( …, A2 )

56 56 XQ Evaluierung [[ { for $book in //book return if (some $author in $book/author satisfies $author/text()=A1) then $book else ()} ]] 0 () [[for $book in //book return if (some $author in $book/author satisfies $author/text()=A1) then $book else ()]] 0 () l=[[//book]] 0 () = [ A1 T1, A2 T2 ] [[if (some …)]] 1 (l 1 ) + [[if (some …)]] 1 (l 2 ) [ A1 T1 ] + [[if (some $author in $book/author satisfies $author/text()=A1) then $book else ()]] 1 ( A2 T2 ) [[for $author in $book/author return $author/text()=A1]] 1 ( A2 T2 ) l =[[$book/author]] 1 ( A2 T2 ) = [ A2 ] [[$author/text()=A1]] 2 ( …, A2 ) [] [[$author/text()]] 2 (…) [A2] [[A1]] 2 (…) [A1]

57 57 XQ Evaluierung [[ { for $book in //book return if (some $author in $book/author satisfies $author/text()=A1) then $book else ()} ]] 0 () [[for $book in //book return if (some $author in $book/author satisfies $author/text()=A1) then $book else ()]] 0 () l=[[//book]] 0 () = [ A1 T1, A2 T2 ] [[if (some …)]] 1 (l 1 ) + [[if (some …)]] 1 (l 2 ) [ A1 T1 ] + [[if (some $author in $book/author satisfies $author/text()=A1) then $book else ()]] 1 ( A2 T2 ) [[for $author in $book/author return $author/text()=A1]] 1 ( A2 T2 ) [] l =[[$book/author]] 1 ( A2 T2 ) = [ A2 ] [[$author/text()=A1]] 2 ( …, A2 ) []

58 58 XQ Evaluierung [[ { for $book in //book return if (some $author in $book/author satisfies $author/text()=A1) then $book else ()} ]] 0 () [[for $book in //book return if (some $author in $book/author satisfies $author/text()=A1) then $book else ()]] 0 () l=[[//book]] 0 () = [ A1 T1, A2 T2 ] [[if (some …)]] 1 (l 1 ) + [[if (some …)]] 1 (l 2 ) [ A1 T1 ] + [[if (some $author in $book/author satisfies $author/text()=A1) then $book else ()]] 1 ( A2 T2 ) [] [[for $author in $book/author return $author/text()=A1]] 1 ( A2 T2 ) [] l =[[$book/author]] 1 ( A2 T2 ) = [ A2 ] [[$author/text()=A1]] 2 ( …, A2 ) [] [[()]] 1 ( A2 T2 ) [] []

59 59 XQ Evaluierung [[ { for $book in //book return if (some $author in $book/author satisfies $author/text()=A1) then $book else ()} ]] 0 () [[for $book in //book return if (some $author in $book/author satisfies $author/text()=A1) then $book else ()]] 0 () [ A1 T1 ] l=[[//book]] 0 () = [ A1 T1, A2 T2 ] [[if (some …)]] 1 (l 1 ) + [[if (some …)]] 1 (l 2 ) [ A1 T1 ] + [] [[if (some $author in $book/author satisfies $author/text()=A1) then $book else ()]] 1 ( A2 T2 ) [] [[for $author in $book/author return $author/text()=A1]] 1 ( A2 T2 ) [] l =[[$book/author]] 1 ( A2 T2 ) = [ A2 ] [[$author/text()=A1]] 2 ( …, A2 ) [] [[()]] 1 ( A2 T2 ) []

60 60 XQ Evaluierung [[ { for $book in //book return if (some $author in $book/author satisfies $author/text()=A1) then $book else ()} ]] 0 () [ A1 T1 ] [[for $book in //book return if (some $author in $book/author satisfies $author/text()=A1) then $book else ()]] 0 () [ A1 T1 ] l=[[//book]] 0 () = [ A1 T1, A2 T2 ] [[if (some …)]] 1 (l 1 ) + [[if (some …)]] 1 (l 2 ) [ A1 T1 ] + [] [[if (some $author in $book/author satisfies $author/text()=A1) then $book else ()]] 1 ( A2 T2 ) [] [[for $author in $book/author return $author/text()=A1]] 1 ( A2 T2 ) [] l =[[$book/author]] 1 ( A2 T2 ) = [ A2 ] [[$author/text()=A1]] 2 ( …, A2 ) [] [[()]] 1 ( A2 T2 ) []

61 61 XQ: 2 Arten von Gleichheit Deep Equality Vergleiche Bäume als Werte z.B.: n1 deep-equal n2 n2 deep-equal n7 n3 = deep-equal n10 n4 = deep-equal n11 n4 deep-equal n10 Atomic Equality Vergleiche Blätter als Werte z.B.: n4 = atomic n11 n4 atomic n9 n1: people n2: person n4: Karln6: Auer n7: person n5: lnn3: fn n9: Auern11: Karl n10: fnn8: ln

62 62 XQuery – Komplexere Beispiele { for $b in doc("doc.xml")//book where fn:count($b/author) > 0 return { $b/title } { for $a in $b/author[position()<=2] return $a } { if (fn:count($b/author) > 2) then else () } } Für jedes Buch mit mindestens einem Autor, gib den Titel und die ersten beiden Autoren aus und ein leeres et-al-Element wenn das Buch weitere Autoren besitzt XQuery

63 63 XQuery – Komplexere Beispiele Finde den minimalen Preis für jedes Buch und gib ihn in der Form eines minprice-Elements mit dem Titel des Buchs als title-Attribut aus. { let $doc := doc("doc.xml") for $t in fn:distinct-values($doc//book/title) let $p := $doc//book[title = $t]/price return { fn:min($p) } } XQuery

64 64 XQuery – Komplexere Beispiele Gib alle Paare von Büchern aus, die unterschiedliche Titel aber die selben Autoren (möglicherweise in unterschiedlicher Reihenfolge) haben. { for $book1 in doc("doc.xml")//book, $book2 in doc("doc.xml")//book let $aut1:=for $a in $book1/author order by $a/last, $a/first return $a let $aut2 := for $a in $book2/author order by $a/last, $a/first return $a where $book1 << $book2 and not($book1/title = $book2/title) and fn:deep-equal($aut1, $aut2) return { $book1/title } { $book2/title } } XQuery Annahme: Autoren haben die Form FIRSTNAME LASTNAME <<: vor

65 65 Literatur und Links Buch XQuery from the Experts, Addison Wesley (Kapitel 1) (Howard Katz, Don Chamberlin, Denise Draper, Mary Fernandez, Michael Kay, Jonathan Robie, Michael Rys, Jerome Simeon, Jim Tivy, Philip Wadler) http://www.datadirect.com/developer/xml/xquery/docs/katz_c01.pdf XQuery Tutorial: http://www.w3schools.com/xquery/default.asp W3C XQuery: http://www.w3.org/TR/2007/REC-xquery-20070123/ W3C XQuery Functions: http://www.w3.org/TR/xpath-functions/ Galax XQuery Engine (installiert in CIP-Pools): http://www.galaxquery.org/


Herunterladen ppt "1 XQuery Informationssysteme, 14.06.2007 Vortragender: Michael Schmidt."

Ähnliche Präsentationen


Google-Anzeigen