Search code examples
xmlxpathxqueryexist-dbaddressing-mode

Error with display in eXist-db using XPath with XQuery


I'm trying to show only the belows elements of a node by name.

In Xpath here is my statment: //akweny[parent::akwen/nazwa="Atlantycki"]

And here is my XML file

<?xml version="1.0" encoding="utf-8"?>
    <akweny>
        <akwen>
            <nazwa>Atlantycki</nazwa>
            <typ>ocean</typ>
            <powierzchnia>106450</powierzchnia>
            <akweny>
                <akwen>
                    <nazwa>Północne</nazwa>
                    <typ>morze</typ>
                    <powierzchnia>750</powierzchnia>
                </akwen>
                <akwen>
                    <nazwa>Batyckie</nazwa>
                    <typ>morze</typ>
                    <powierzchnia>386</powierzchnia>
                    <akweny>
                        <akwen>
                            <nazwa>Botnicka</nazwa>
                            <typ>zatoka</typ>
                            <powierzchnia>117</powierzchnia>
                        </akwen>
                    </akweny>
                </akwen>
            </akweny>
        </akwen>
        <akwen>
            <nazwa>Spokojny</nazwa>
            <typ>ocean</typ>
            <powierzchnia>179700</powierzchnia>
        </akwen>
    </akweny>

And here is my DTD

<?xml version="1.0" encoding="utf-8"?>
<!ELEMENT akweny (akwen+)>
<!ELEMENT akwen (nazwa, typ, powierzchnia, akweny?)>
<!ELEMENT nazwa (#PCDATA)>
<!ELEMENT typ (#PCDATA)>
<!ELEMENT powierzchnia (#PCDATA)>

And here is my Xquery statement

declare function app:PokazRodzica($node as node(), $model as map(*), $name as xs
:string?) {

<table border="1" width="100%">
<th>Podrzędne</th><th>Nazwa</th><th>Typ</th><th>Powierzchnia</th><th>Edycja</th>
{
    (:DOBRE ZAPYTANIE
    for $x in doc('/db/Dane/akweny.xml/')//akweny[parent::akwen/nazwa="Atlantycki"]
    parent::akwen/nazwa="Atlantycki"]/text()
    :)

    for $x in doc('/db/Dane/akweny.xml/')//akweny[parent::akwen/nazwa="Atlantycki"]
    let $nazwa := $x/nazwa
    let $typ := $x/typ
    let $powierzchnia := $x/powierzchnia
        return 
           <tr>
            <th><img src="/exist/apps/Obrazki/lupa.jpg" alt="Podrzedny" /> {count($nazwa/text())} KLIK</th>
            <th bgcolor="#F46978">{$nazwa}</th>
            <th>{$typ}</th>
            <th>{$powierzchnia}</th>
            <th>Edytuj</th>
            </tr>
}
</table>
};

For fast testing Xpath with my xml u can use this tool: http://www.online-toolz.com/tools/xpath-editor.php

The big problem is in Exist-DB data are displayed incorrectly.

My resultat is nothink... but it should be node parents...

I have no idea what I'm doing wrong. Please help me.


Solution

  • Before you start using eXist-db's templating system, you should test your XPath in eXide.

    You refer to the document with /db/Dane/akweny.xml/. Though this gives no error, you should remove the last "/", since it is not part of the document name.

    Then you should have a look at your XPath, //akweny[parent::akwen/nazwa="Atlantycki"]. Are you trying to find any akweny that have a parent akwen with a nazwa child with the value of "Atlantycki"? There is only one,

    <akweny>
        <akwen>
            <nazwa>Północne</nazwa>
            <typ>morze</typ>
            <powierzchnia>750</powierzchnia>
        </akwen>
        <akwen>
            <nazwa>Batyckie</nazwa>
            <typ>morze</typ>
            <powierzchnia>386</powierzchnia>
            <akweny>
                <akwen>
                    <nazwa>Botnicka</nazwa>
                    <typ>zatoka</typ>
                    <powierzchnia>117</powierzchnia>
                </akwen>
            </akweny>
        </akwen>
    </akweny>
    

    Or are your trying to retrieve something else?

    Try entering

    doc('/db/Dane/akweny.xml')//akweny[parent::akwen/child::nazwa eq "Atlantycki"]
    

    in eXide and tune your XPath to get the results you want, by adding one step at a time.

    Perhaps you are looking for something like this:

    <table border="1" width="100%">
    <th>Podrzędne</th><th>Nazwa</th><th>Typ</th><th>Powierzchnia</th><th>Edycja</th>
    {
    let $nodes := doc('/db/Dane/akweny.xml/')//akweny[parent::akwen/nazwa="Atlantycki"]
    for $x in $nodes/*
    let $nazwa := $x/nazwa/text()
    let $typ := $x/typ/text()
    let $powierzchnia := $x/powierzchnia/text()
        return 
           <tr>
            <th><img src="/exist/apps/Obrazki/lupa.jpg" alt="Podrzedny" /> {count($nazwa/text())} KLIK</th>
            <th bgcolor="#F46978">{$nazwa}</th>
            <th>{$typ}</th>
            <th>{$powierzchnia}</th>
            <th>Edytuj</th>
            </tr>
    }</table>
    

    When you have finished with this, remember that you have to call your app:PokazRodzica() function somewhere, for instance in index.html. The function in itself does not display anything (as wst wrote above).

    Please correct the spelling in your title to "Error with display in eXist-db using XPath with XQuery".