Metasuche/neue Schnittstelle
Die Metasuche http://meta.genealogy.net/ hat eine stark vereinfachte Schnittstelle bekommen, so dass die Anbindung weiterer Suchmaschinen einfacher geworden ist.
Schnittstelle
Per HTTP POST[1] werden mit Content-Type application/x-www-form-urlencoded[2] folgende Anfrage-Parameter übertragen:
- lastname
- placeid - GOV-Kennung des Ortes
- placename
- since - (optional) liefere nur Einträge, die jünger als das angegebene Datum sind. Wird dieser Parameter nicht ausgewertet, dann funktionieren die genealogy.net-Alerts nicht. Datum der Form yyyy-mm-dd
Die Werte der Anfrage werden dabei mit UND verknüpft. Es sollte selbstverständlich sein, dass auch nach Nicht-ASCII-Zeichen (z.B. Umlauten) gesucht werden kann. Standardmäßig werden Anfragen in UTF-8 kodiert geschickt. Es ist aber auf Seiten der Metasuche auch möglich, auf ISO-8859-1 umzuschalten.
Erwartet wird ein Ergebnis (Content-Type muss auf 'text/xml' gesetzt sein!) in der folgenden Form:
<result>
<database>
<name>GEDBAS</name>
<url>http://gedbas.genealogy.net</url>
<entry>
<lastname>lastname 0</lastname>
<firstname>firstname 0</firstname>
<details>details 0</details>
<url>http://localhost/data/0</url>
</entry>
<entry>
<lastname>lastname 1</lastname>
<firstname>firstname 1</firstname>
<details>details 1</details>
<url>http://localhost/data/1</url>
</entry>
...
<more>true</more> <!-- wenn das "more"-Element enthalten ist, zeigt das an, dass es noch mehr Treffer als die zurückgelieferten gibt -->
</database>
</result>
Bei einer leeren Suchanfrage (weder lastname, noch placeid, noch placename gesetzt) sollte ein leeres Ergebnis zurückgegeben werden:
<result>
<database>
<name>GEDBAS</name>
<url>http://gedbas.genealogy.net</url>
</database>
</result>
Das gleiche Ergebnis soll auch zurückgeliefert werden, wenn keine Treffer gefunden werden:
<result>
<database>
<name>GEDBAS</name>
<url>http://gedbas.genealogy.net</url>
</database>
</result>
Weitere Hinweise
- Dürfen höchsten 20 Ergebnisse zurückgeliefert werden?
Nein, man kann auch nur 5 Treffer direkt liefern und den Rest auf der eigenen Webseite anzeigen. Zu viele Einträge machen jedoch die Ergebnisliste für den Nutzer unübersichtlich. Von daher scheint uns 20 Einträge pro Datenbank ein guter Wert zu sein.
- Wie ist mit der Abfrage mehrerer Datenbanken zu verfahren?
Da innerhalb eines <result>-Elements mehrere <database>-Elemente erlaubt sind, kann eine Anfrage auch mehrere Datenbanken zurückliefern. Das liegt im Ermessen des Betreibers der zu durchsuchenden Datenbanken. Zu berücksichtigen ist jedoch, dass der Nutzer beim Start der Anfrage nur einen einzigen Eintrag auswählt und möglicherweise verwirrt ist, wenn Ergebnisse verschiedener Datenbanken zurückgegeben werden.
Testen
Mit curl kann man recht einfach ausprobieren, ob man die Schnittstelle richtig implementiert hat. Hier sind ein paar Beispielabfragen:
curl -v -XPOST -H "Accept: text/xml" -H "Content-Type: application/x-www-form-urlencoded" -d "lastname=Meyer" https://URL
curl -v -XPOST -H "Accept: text/xml" -H "Content-Type: application/x-www-form-urlencoded" -d "lastname=Meyer&placename=Berlin" https://URL
Wichtig ist, dass als Content-Type text/xml zurückgeliefert wird. Im Body sollte auch kein HTML-Code oder ähnliches enthalten sein, nur ein XML-Dokument.
Beispiel-Implementierungen
PHP
<?php
# Eine Hilfsfunktion, die den Inhalt der Parameter aus der HTTP-Anfrage ausliest.
function get_http_var($name, $default=''){
global $_GET, $_POST;
if (array_key_exists($name, $_GET)){return trim($_GET[$name]);}
if (array_key_exists($name, $_POST)){return trim($_POST[$name]);}
return $default;
}
$lastname = get_http_var('lastname');
$placename = get_http_var('placename');
$govId = get_http_var('placeid');
header('Content-type: text/xml');
echo "<result>";
echo "<database>";
echo "<name>Beispiel</name>";
echo "<url>http://example.org</url>";
# An dieser Stelle die Suche durchfüren und über die Ergebnisse iterieren
for( $i = 0; $i < $anzahl_ergebnisse; $i++ ) {
echo "<entry>";
echo "<lastname>...</lastname>";
echo "<firstname>...</firstname>"; # Wenn die Datenbank keinen Nachnamen enthält, kann dieses Element weggelassen werden
echo "<details>...</details>"; # Die Details können beliebige Informationen enthalten, z.B. Geburts- und Sterbedatum
echo "<url>http://example.org/anzeige?id=...</url>"; # ein direkter Link auf den Datensatz
echo "</entry>";
} # für die Ergebnisse
# Wenn es noch mehr Ergebnisse als die zurückgelieferten gibt, wird ein Element "more" eingefügt.
if( $anzahl_ergebnisse > 20 ) {
echo "<more>true</more>";
}
echo "</database>";
echo "</result>";
?>
Grails
if( !(params.lastname || params.placename || params.placeid) )
render(contentType:"text/xml") {
error()
}
def criteria = Entry.createCriteria()
def results = criteria.list([max:21]) {
// Suche durchführen
}
render(contentType:"text/xml") {
'result' {
database {
name('Datenbank Historischer Adressbücher')
url('http://adressbuecher.genealogy.net')
for( int i = 0; i< Math.min(results.size(),20); i++) {
Entry e = results[i]
entry {
lastname(e.lastname)
firstname(e.firstname)
details("${e.book?.title} ${e.book?.year}")
url(g.createLink(controller:'entry',action:'show',id:e.id,absolute:true))
}
}
if( results.size()> 20 )
more('true')
}
}
- ↑ Der HTTP-Standard macht leider widersprüchliche Angabe, wie nicht-ASCII-Zeichen bei GET-Anfragen zu behandeln sind. Das hat früher immer wieder für Probleme gesorgt. Bei einem POST kann man den Zeichensatz angeben, so dass die Probleme dort nicht auftreten.
- ↑ http://en.wikipedia.org/wiki/POST_(HTTP)#Use_for_submitting_web_forms