[MarkLogic Dev General] xpath string construction

Geert Josten Geert.Josten at daidalos.nl
Sat Oct 11 10:33:51 PDT 2008


When it concerns only one element, you could always try something like *[local-name() = $media]. And when it concerns a relatively straightforward path like /a/b/c, then one could try to tokenize the string and perform local-name() matches recursively, but it is cumbersome. And I don't think you want to go this way.. ;)

Also the remarks on multiple users changing the same document 'simultaniously' are true. I thought one of the other responses was using element ID's, which makes both retrieving those elements easier and prevents mistakes when absolute paths using positions are no longer valid because of mutations by other people. It is relatively safe, but it requires the content to have either ID attributes or something equivalent. Not the case for you I guess.. :(

Best approach would be to disallow editing by two persons simultaniously. A locking mechanism with a checkin/out kind of functionality is the most common. But for simple cases that could simply be overkill. Applies to you, am I right?

There is one other approach that is in use on internet: no locking is performed, but the system somehow is able to keep track of the version each editor is editing. At commit the version being edited is compared to the one in the database at commit time. If it doesn't match, the commit is not performed and the editor is warned that someone else has changed the contents meantime. Usually it is bad luck for the editor. He will have to retrieve the document for editing once more and apply the changes a second time. If he is lucky, he might be able to use copy/paste..

Not very friendly, but at least it is something. And keeping track of a version doesn't need to be difficult. A CRC comparison should suffice I guess, one might be able to write a pure-XQuery function for that. Alternatively, just retrieving the timestamp using MarkLogic extensions, might be easier.. ;-)

Good luck,


Drs. G.P.H. Josten

Daidalos BV
Source of Innovation
Hoekeindsehof 1-4
2665 JZ Bleiswijk
Tel.: +31 (0) 10 850 1200
Fax: +31 (0) 10 850 1199
KvK 27164984
De informatie - verzonden in of met dit emailbericht - is afkomstig van Daidalos BV en is uitsluitend bestemd voor de geadresseerde. Indien u dit bericht onbedoeld hebt ontvangen, verzoeken wij u het te verwijderen. Aan dit bericht kunnen geen rechten worden ontleend.

> From: general-bounces at developer.marklogic.com
> [mailto:general-bounces at developer.marklogic.com] On Behalf Of
> Eric Palmitesta
> Sent: vrijdag 10 oktober 2008 20:43
> To: ML Developer Mailing List
> Subject: [MarkLogic Dev General] xpath string construction
> Is there a specific reason why one can't construct an xpath
> out of a string?
> For example,
> let $media := 'book' (: or 'journal', or 'article' :) return
>    doc('/path/to/file.xml')/path/to/$media/title
> Another use case, I want to display a list of items, and
> offer a 'delete' link for each item.
> lets say /people.xml contained the following:
>    <people>
>      <person name="bob" />
>      <person name="jim" />
>      <person name="bob" />
>      <person name="ryan" />
>    </people>
> So I'd display something like:
> for $person in doc('/people.xml')/people/person return
>    <div>
>      $person/@name
>      <a href="delete.xqy?path={ xdmp:path($person) }>delete</a>
>    </div>
> This will give me nice delete links like
> "delete.xqy?path=/people/person[1]", but in the supposed
> delete.xqy, I'd want to do something similar to:
> let $file := '/people.xml'
> let $person := xdmp:get-request-field('path') return
>    xdmp:node-delete(doc($file)/$person)
> I can't, of course, the doc call will be fine but I can't
> construct xpath with a string.  And the node-delete (and any
> other node-manipulation function) requires actual nodes, not strings.
> I end up having to write eval-based utility functions:
> define function util:remove-element($uri as xs:string, $xpath
> as xs:string) {
>         let $node := concat("doc('", $uri, "')", $xpath)
>         return
>                 xdmp:eval(concat("xdmp:node-delete(", $node, ")")) }
> Please tell me I'm all wrong and there's a better way.
> Cheers,
> Eric
> _______________________________________________
> General mailing list
> General at developer.marklogic.com
> http://xqzone.com/mailman/listinfo/general

More information about the General mailing list