2010-12-17 2 views
4

ich eine XQuery zu schreiben versuchen zurückzukehren, die alle Textknoten finden würden, das einen bestimmten Schlüsselwort in einer XML-Datei enthalten. Der Textknoten ist lang, daher möchte ich einen Teilstring (mit einer gewünschten Länge) des Texts beginnend mit dem übereinstimmenden Schlüsselwort zurückgeben.Mit functx: index-of-Match-first in XQuery eine Teiltextknoten

Samplefile.xml

<books> 
<book> 
    <title>linear systems</title> 
    <content>vector spaces and linear system analysis </content> 
</book> 
<book> 
    <title>some title</title> 
    <content>some content</content> 
</book> 
</books> 

samplexquery.xq

declare namespace functx = "http://www.functx.com"; 

for $match_result in /*/book/*[contains(.,'linear')]/text() 
    return substring($match_result, functx:index-of-match-first($match_result,'linear'), 50) 

Ich erwarte, dass das Ergebnis [lineare Systeme, lineare Systemanalyse] erhalten. Der Titelknoten des ersten Buches enthält das Wort "linear". Geben Sie 50 Zeichen beginnend mit 'linear ....' zurück. Ähnlich für den Inhaltsknoten des ersten Buches.

Ich bin mit XQuery 1.0 und I enthalten den Namespace functx wie bei im gezeigten Beispiel: http://www.xqueryfunctions.com/xq/functx_index-of-match-first.html

Aber das mir einen Fehler geben: [XPST0017] Unbekannte Funktion „functx: index-of-Match- zuerst(...)".

Danke, Sony

+0

Gute Frage, +1. Siehe meine Antwort für eine Erklärung und Lösung. :) –

Antwort

2

I am using XQuery 1.0 and I included the namespace functx as shown in the example at: http://www.xqueryfunctions.com/xq/functx_index-of-match-first.html

But, this is giving me an error: [XPST0017] Unknown function "functx:index-of-match-first(...)".

Es reicht nicht aus, nur den Namensraum zu deklarieren.

Sie müssen auch den Code der Funktion haben. Nur der Standard XQuery and XPath functions and operators ist in der Sprache vordefiniert.

Dieser korrigierte Code:

declare namespace functx = "http://www.functx.com"; 
declare function functx:index-of-match-first 
    ($arg as xs:string? , 
    $pattern as xs:string) as xs:integer? { 

    if (matches($arg,$pattern)) 
    then string-length(tokenize($arg, $pattern)[1]) + 1 
    else() 
} ; 

for $match_result in /*/book/*[contains(.,'linear')]/text() 
    return substring($match_result, functx:index-of-match-first($match_result,'linear'), 50) 

wenn sie auf dem vorgesehenen XML Dokument (mit mehreren nicht-Wohlgeformtheits- Fehler korrigiert) angewendet:

<books> 
    <book> 
    <title>linear systems</title> 
    <content>vector spaces and linear system analysis </content> 
    </book> 
    <book> 
    <title>some title</title> 
    <content>some content</content> 
    </book> 
</books> 

erzeugt das erwartete Ergebnis:

linear systems linear system analysis 

Es ist eine gute Praxis, die import module Direktive zu verwenden, um Module aus vorhandenen Bibliotheken von Funktionen zu importieren.

+0

Oh ich dachte, das waren vordefinierte Funktionen. Sieht so aus, als wären sie wiederverwendbare Funktionen. Vielen Dank :) – sony

+0

@sony: Es ist eine gute Praxis, die 'import module' Direktive zu verwenden, um Module aus vorhandenen Funktionsbibliotheken zu importieren –