Losung 8

Werbung
Institut für Informationssysteme
Dr. Robert Marti
Claude Barthels
David Sidler
Informationssysteme für Ingenieure
Herbstsemester 2016
Musterlösung 8
Lösung 8.1
1.
XML Anwendungsbeispiel
• Binär Z.B. Object Streams. Das Format ist kompakt, aber nicht für Menschen lesbar. Es bestehen zudem
Inkompatibilitäten zwischen Formaten, z.B. Word Dokumente vs. Open Office Dokumente, oder serialisierte Java Objekte vs. serialisierte C++ Objekte.
• Plain Text Einfache Handhabung und für Menschen lesbar. Wenn das Format sich ändert (zusätzliche
Information hinzufügen) muss der Parser umgeschrieben werden.
• XML Diese Variante erhöht die Kompatibilität mit anderen Systemen (andere Implementierung des eigenen Systems, neue Version des eigenen Systems, Traffic-Analysers etc). Erweiterung der Nachricht kein
Problem (ältere Versionen lesen nur die Elemente, die sie kennen und ignorieren neue Elemente). Ausserdem gibt es für XML Libraries, die das Parsen und Kreieren von XML Dokumenten und deren Korrektheit
(well-formedness) übernehmen. Nachteil: Grössere Nachrichten. Dieser Nachteil kann aber mit Komprimierung (z.B. ZIP) kompensiert werden.
2. Wenn ein Peer nach einer Datei sucht, so verfasst es ein request Dokument. In dieses schreibt es seine eigene
id als Quelle und den Namen der gesuchten Datei. Falls nach einer ganz bestimmten Datei gesucht wird (die
man schon kennt), könnte man auch (zusätzlich) einen Hashwert für die Datei einfügen. Dieses Anfragedokument schickt das Peer nun an seine Nachbarn. Hat ein Nachbar die gesuchte Datei nicht, so trägt er seine id im
path Element des Dokumentes ein und schickt die Nachricht an seine Nachbarn weiter, falls deren id nicht
schon im path steht. Wichtig ist, dass der Inhalt des path Elementes geordnet ist, also neue Einträge zum
Beispiel immer unten angefügt werden, damit der Pfad später zurückverfolgt werden kann.
<request>
<source>
<peer id="12" />
</source>
<file>
<name>Arcade Fire</name>
...
</file>
<path>
<peer id="18" />
<peer id="81" />
<peer id="9" />
...
</path>
</request>
Besitzt ein Peer eine Datei, die einem eingehenden request entspricht, so kann es eine response Nachricht
verfassen. Dafür kopiert es den Inhalt des source Elements in das destination Element und fügt sich
selber als source ein. Die Information über die Datei bleibt gleich, hinzu kommt ein data Element, das die
gesuchte Datei im Binärformat enthält. Der path Teil der Anfrage wird ebenfalls in die Antwort kopiert. Auf
dem Rückweg der Antwort durch das P2P Netz kann jedes Peer nach dem Erhalt der Nachricht seine id als
unterstes Element aus der Liste im path entfernen. Wir verwenden also für die Abwicklung von Frage/Antwort
das path Element als Stack.
<response>
<source>
<peer id="27" />
</source>
<destination>
<peer id="12" />
</destination>
<file>
<name>Arcade Fire</name>
...
</file>
<data>...01101000100101...</data>
<path>
<peer id="18" />
<peer id="81" />
<peer id="9" />
...
</path>
</response>
3. <!DOCTYPE request [
<!ELEMENT request (source, file, path)>
<!ELEMENT source
(peer)>
<!ELEMENT file
(name, ...)>
<!ELEMENT path
(peer*)>
<!ELEMENT peer
EMPTY>
<!ELEMENT name
(CDATA)>
<!ATTLIST peer
id CDATA #REQUIRED>
]>
<!DOCTYPE response [
<!ELEMENT response (source, destination, file, data, path)>
<!ELEMENT source
(peer)>
<!ELEMENT destination
(peer)>
<!ELEMENT file
(name, ...)>
<!ELEMENT data
(CDATA)>
<!ELEMENT path
(peer*)>
<!ELEMENT peer
EMPTY>
<!ELEMENT name
(CDATA)>
<!ATTLIST peer
id CDATA #REQUIRED>
]>
2
Lösung 8.2
XQuery
1. <countries>
{
for $c in /mondial/country
return
<country>
<name>{string($c/name)}</name>
<area>{string($c/@area)}</area>
<population>{string($c/population)}</population>
</country>
}
</countries>
2. <result>
{
for
$c in //country,
$o in //organization
where $c/@capital = $o/@headq
return
<answer>
<country>{string($c/name)}</country>
<organization>{string($o/name)}</organization>
</answer>
}
</result>
3. <result>
{
for
$c in //country,
$p in $c/province
return
<answer>
<country>{string($c/name)}</country>
<province>{string($p/name)}</province>
</answer>
}
</result>
4. <result>
{
for $c in //country
return
<answer>
<country>{string($c/name)}</country>
{
for $p in $c/province
return
<province>{string($p/name)}</province>
}
</answer>
}
</result>
3
Diese Anfrage liefert auch answer Elemente, wenn für ein Land keine Provinzen gespeichert sind. Wenn
wir diese Länder ohne Provinzen herausfiltern wollen, so können wir das mit einem Zusatz von where
$c/province vor dem return Statement erreichen.
5. <result>
{
for $c in //country
return
<country name="{$c/name}">
{
for $city in $c//city
return
<city>{string($city/name)}</city>
}
</country>
}
</result>
6. <result>
There are
{for $m in /mondial return count($m//country)}
countries in the database.
{
for $m in /mondial
return sum(
for $c in $m//country
where $c//city/population > 1000000
return 1
)
}
of them have a city with more than 1Mio inhabitants.
<countries>
{
for $c in //country
where
$c//city/population > 1000000
return
<country>{$c/name}</country>
}
</countries>
</result>
Bei dieser Anfrage wird die Auswertung der Städte mit mehr als 1Mio. Einwohnenr zweimal gemacht. Um dies
zu vermeiden kann man mittels let ein Zwischenresultat definieren, ähnlich einer View in SQL.
let $countrycount :=
for $m in /mondial
return count($m//country)
let $matches :=
for $c in //country
where $c//city/population > 1000000
return <country>{$c/name}</country>
4
return
<result>
<totalcountries count="{$countrycount}" />
<matchingcountries count="{count($matches)}" />
<countries>{$matches}</countries>
</result>
5
Herunterladen