Mit einem externen Präprozessor können Dokumente geändert werden, bevor sie indiziert werden. Dies ermöglicht es beispielsweise, Binärdaten in Text umzuwandeln oder Metadaten (etwa von Bildern) zu extrahieren oder zu erzeugen und anschließend zu indizieren. Dadurch können die betreffenden Dokumente auch oder besser über die Suche gefunden werden.
Dokumente beliebiger MIME-Typen können den jeweils zu verwendenden externen Präprozessoren über
den Abschnitt
indexing
in der Systemkonfiguration zugeordnet werden. Als ein externer
Präprozessor kann jedes geeignete Programm angegeben werden. Optional können einem solchen Programm
Argumente übergeben werden.
Das Präprozessor-Programm erhält vom Search Engine Server das zu indizierende Dokument in Form
eines serialisierten XML-Dokuments über stdin
. Der Präprozessor modifiziert dieses
XML-Dokument in der gewünschten Weise und gibt es anschließend an den Search Engine Server auf
stdout
zurück. Dieser indiziert nun das modifizierte Dokument. Beispiel:
Ursprüngliche Daten:
<ses-indexDoc docId="2148" collection="cm-contents" mimeType="application/vnd.ms-excel"> <title encoding="plain">Ein Beispiel mit Excel-Daten</title> <keyword encoding="plain">Beispiel</keyword> <blob encoding="stream" mimeType="application/vnd.ms-excel"> /Fiona_671/instance/default/tmp/externalPreprocessor/1.dat </blob> </ses-indexDoc>
Geänderte Daten:
<ses-indexDoc docId="2148" collection="cm-contents" mimeType="application/vnd.ms-excel"> <title encoding="plain">Excel-Daten als Text</title> <keyword encoding="plain">Beispiel</keyword> <blob encoding="stream" mimeType="text/plain"> /Fiona_671/instance/default/tmp/text_data.dat </blob> </ses-indexDoc>
Das XML-Dokument enthält die zu indizierenden Felder (die Namen der XML-Elemente) und deren Werte
(die Inhalte der XML-Elemente). Ein Feldwert kann direkt (encoding: plain
) oder kodiert
angegeben sein. Das Encoding wird über das Tag-Attribut encoding
des Feld-Elements
bestimmt, das folgende Werte haben kann:
plain
: Der Feldwert entspricht dem Inhalt des XML-Elements.base64
: Der Feldwert ergibt sich aus dem
base64-dekodierten Inhalt des XML-Elements.stream
: Der Feldwert ist in der Datei enthalten,
deren Pfad im Inhalt des XML-Elements angegeben ist.Bei allen Kodierungen außer plain
wird zusätzlich der MIME-Typ des
Dokuments im Feld-Element-Attribut mimeType
übermittelt. Wenn der MIME-Typ während der
Vorverarbeitung geändert wird, muss auch das mimeType
-Attribut auf den resultierenden
MIME-Typ gesetzt werden. Ist die Kodierung nicht plain
, wird ein Feldwert nur dann
indiziert, wenn der angegebene MIME-Typ dem Muster text/*
genügt. Mit anderen Worten:
wenn ein Präprozessor base64-kodierte oder per Streaming inkludierte Feldwerte liefert, muss er
deren MIME-Typ auf einen Text-Typ setzen.
Der zu verwendende Präprozessor kann zusammen mit den MIME-Typen, für die er zuständig ist, sowie
den ihm zu übergebenden Argumenten in der Konfigurationsdatei indexing.xml
eingetragen
werden. Der betreffende Abschnitt sieht beispielsweise so aus:
... <contentPreprocessors type="list"> <preprocessor> <mimeTypes type="list"> <mimeType>application/pdf</mimeType> </mimeTypes> <processor type="external"> bin/tclsh </processor> <processorArguments type="list"> <argument>/Fiona_671/instance/default/script/custom/pdf2TxtWrapper.tcl</argument> </processorArguments> </preprocessor> ... </contentPreprocessors> ...
Hier sind als auszuführendes Programm der Tcl-Interpreter und als ein argument
in
processorArguments
der Name des von ihm auszuführenden Skripts,
pdf2TxtWrapper.tcl
, angegeben. Das Skript kann nicht beim Start des Search Engine
Servers geladen werden, sollte also nicht im serverCmds
- oder
clientCmds
-Verzeichnis liegen.
Das folgende als Beispiel aufgeführte Skript pdf2TxtWrapper.tcl
zeigt, wie ein im
Feld blob
enthaltenes PDF-Dokument eingelesen und zu Text konvertiert werden kann.
Beachten Sie bitte, dass die Search Cartridge PDF-Dateien auch ohne Zuhilfenahme eines Präprozessors
indizieren kann.
# Libraries package require dom package require base64 proc safeInterp {args} {} source [file join [file dirname [info script]]\ ../../../share/script/common/clientCmds/util.tcl] # Read Data set xmlRequest [read stdin] # Parse XML set docNode [::dom::DOMImplementation parse $xmlRequest] set rootNode [::dom::document cget $docNode -documentElement] # Select and handle element "blob" set blobElement [lindex [::dom::selectNode $rootNode descendant::blob] 0] array set attributes [array get [$blobElement cget -attributes]] set blobTextNode [$blobElement cget -firstChild] if {$blobTextNode ne ""} { set value [$blobTextNode cget -nodeValue] if {$value ne ""} { switch $attributes(encoding) { plain { # shouldn't happen with pdf set blob $value } base64 { set blob [::base64::decode $value] } stream { set blobFile $value } } set deletePdfFile 0 if {![info exists blobFile]} { set blobFile "/tmp/convert_me_[pid].pdf" writeFile $blobFile $blob set deletePdfFile 1 } set textFile "/tmp/converted_[pid].txt" # convert using ps2ascii if {![catch { exec ps2ascii $blobFile $textFile }]} { # modify the dom tree $blobTextNode configure -nodeValue $textFile ::dom::element setAttribute $blobElement mimeType "text/plain" ::dom::element setAttribute $blobElement encoding stream } if {$deletePdfFile} { file delete -force $blobFile } } } set xmlToReturn [string trimright [::dom::DOMImplementation serialize $docNode] "\n"] set lines [split $xmlToReturn "\n"] if {[string match "<!D*" [lindex $lines 1]]} { set xmlToReturn [join [lreplace $lines 1 1] "\n"] } # return the (modified) xml data puts -nonewline $xmlToReturn