2010-12-14 2 views
4

Eine Testprobe meiner XML-Datei ist unten dargestellt:XQuery Rückkehr Textknoten, wenn es enthält bestimmtes Keyword

test.xml

<feed> 
    <entry> 
    <title>Link ISBN</title> 
    <libx:libapp xmlns:libx="http://libx.org/xml/libx2" /> 
    </entry> 
    <entry> 
    <title>Link Something</title> 
    <libx:module xmlns:libx="http://libx.org/xml/libx2" /> 
    </entry> 
</feed> 

Jetzt möchte ich eine xquery schreiben, die alle <entry> finden Elemente, die <libx:libapp> als Kind haben. Dann geben Sie für alle solche Einträge den Titel zurück, wenn der Titel ein bestimmtes Schlüsselwort enthält (z. B. Link). In meinem XML-Beispieldokument sollte die Xquery "Link ISBN" zurückgeben.

Meine Probe xquery ist unten dargestellt:

samplequery.xq (hier DOC_NAME ist die XML-Datei, die oben gezeigt und libapp_matchkey ist ein Schlüsselwort wie 'Link')

declare namespace libx='http://libx.org/xml/libx2'; 
declare variable $doc_name as xs:string external; 
declare variable $libpp_matchkey as xs:string external; 
let $feeds_doc := doc($doc_name) 

for $entry in $feeds_doc/feed/entry 
    (: test whether entry has libx:libapp child and has "Link" in its title child :) 
    where ($entry/libx:libapp and $entry/title/text()[contains(.,$libapp_matchkey)]) 
    return $entry/title/text() 

Diese xquery kehrt null anstelle des erwarteten Ergebnisses 'Link ISBN'. Warum das?

+0

I ersetzt haben '$ food_doc' Erklärung als'/', korrigiert, um die' $ libapp_matchkey' Tippfehler, und es erfolgreich mit dem Eingangsabtastwert runned . –

+0

Gute Frage, +1. Siehe meine Antwort für eine kurze und natürliche One-Liner-Lösung :) –

Antwort

6

Ich möchte eine xquery schreiben, die alle Elemente finden, die als Kind haben. Dann geben alle solche Einträge für den Titel zurück, wenn der Titel ein gegebenes Schlüsselwort (wie Link) enthält.

Verwenden Sie einfach:

/*/entry[libx:libapp]/title[contains(.,'Link')]/text() 

Wrapping diese XPath-Ausdruck in XQuery bekommen wir:

declare namespace libx='http://libx.org/xml/libx2'; 
/*/entry[libx:libapp]/title[contains(.,'Link')]/text() 

wenn auf der mitgelieferten XML-Dokument angelegt:

<feed> 
    <entry> 
    <title>Link ISBN</title> 
    <libx:libapp xmlns:libx="http://libx.org/xml/libx2" /> 
    </entry> 
    <entry> 
    <title>Link Something</title> 
    <libx:module xmlns:libx="http://libx.org/xml/libx2" /> 
    </entry> 
</feed> 

das gewünschte, korrekte Ergebnis hergestellt:

Link ISBN 
+0

Ich sehe die folgende Ausnahme, wenn ich dies versuche: für $ Eintrag in $ feeds_doc/atom: feed/atom: Eintrag zurück/*/$ Eintrag [libx: libapp]/title [enthält (., 'Link')]/text() Ausnahme im Thread "main" java.io.IOException: Gestoppt in Zeile 9, Spalte 13: [XPDY0002] Kein Kontextelement für 'root()' gesetzt. – sony

+0

@sony: Es gibt keinen $ -Eintrag in meiner Antwort - Sie können eine mögliche Ausnahme für alles bekommen, was nicht meine Antwort ist, aber warum melden Sie dies hier als Kommentar? –

+1

Worauf bezieht sich/*? Ich meine Eintragselemente sind innerhalb Element im Dokument. Wie beziehen Sie sich auf $ feeds_doc/feed – sony