[MarkLogic Dev General] Scaffolding

Eric Palmitesta eric.palmitesta at utoronto.ca
Tue Oct 14 09:29:01 PDT 2008

I've committed my initial version into the xquery commons 

Do you have an account?  Can you commit your changes below?



Geert Josten wrote:
> Hi Eric,
> I think the loss of attributes is being caused by the fact you are actually recreating the complete element when you try to update the text, without copying the original attributes while doing so. :-)
> Pretty simple to fix I guess, but I think it is better to change your path expressions to include the originating text() node into the path, recreate a new text node instead of an element node, and replace the old text node with the new one instead of replacing elements.
> You might want to consider adding separate save buttons, one for each textarea. The top-level save button can handle many updates simultaniously, but if you want to do just one minor update in a single field, you are performing a lot of updates anyway. Just sounds redundant.. :-P
> By using a for loop over child nodes instead of addressing text() and element() nodes directly, you can also fix the lack of support for mixed content elements.
> I replaced your display-element-contents function with this:
> define function display-element-contents($elements as element()*)
> {
>         for $element in $elements
>         return
>                 <ul>
>                         <li>{
>                                 open-tag($element),
>                                 for $node in $element/node()
>                                 return
>                                         if (node-kind($node) = "text") then
>                                                 if (normalize-space($node) = '') then
>                                                         <i style="color:#DDDDDD">whitespace</i>
>                                                 else if (string-length($node) gt 30) then
>                                                         <textarea name="__text__{ xdmp:path($node) }" rows="3" cols="30">{ $node }</textarea>
>                                                 else
>                                                         <input type="text" name="__text__{ xdmp:path($node) }" value="{ $node }"
>                                                         size="{ min((30, string-length($node))) }" />
>                                         else if (node-kind($node) = "element") then
>                                                 display-element-contents($node)
>                                         else
>                                                 <i style="color:#FF0000">{node-kind($node)}</i>,
>                                 close-tag($element)
>                         }&nbsp;{
>                                 if (not($element = root($element))) then add-remove-links($element)
>                                 else ()
>                         }</li>
>                 </ul>
> }
> And I replaced you update-element function with:
> (:
>         Called by save-fields, constructs a new text containing $value, to replace
>         the text residing at $path in $uri.
> :)
> define function update-element($uri as xs:string, $path as xs:string, $value as xs:string)
> {
>         let $old-node := concat("doc('", $uri, "')", $path)
>         let $new-node := concat("text { '", replace($value, "'", "''"), "' }")
>         let $z := xdmp:log(concat("xdmp:node-replace(", $old-node, ", ", $new-node, ")"))
>         return
>                 xdmp:eval(concat("let $old-node := ", $old-node, " return if ($old-node) then xdmp:node-replace($old-node, ", $new-node, ") else ()"))
> }
> You might consider renaming the last to update-text.. ;-)
> Anyhow, with these two replacements, the scaffold editor should be much more robust.
> Only thing I wasn't able to solve was how to handle a proper distinction between files and directories. I was experimenting on a database in which the uri's of my files don't end with an extension. Next to this they just reside in the root, but the xdmp:directory function does not seem to support the uri '/' to refer to the database root. :-(
> Oh, I did found one other anomaly: I have attributes with namespace prefixes in some of my documents. The xdmp:path function does not respect the prefixes, just leaves them out. This causes the replace to fail, because it is unable to resolve the path (returns empty). That is the reason why I added a wrapping if to the evaluated replace statement (added it to update-attribute as well of course).
> Note: I am NOT an experienced MarkLogic user. In fact, I have only 2 weeks experience. Though I am familiar with Xquery and Xpath much longer. I mention this because there might be much better ways to do things like this in MarkLogic, but I am not aware of these. Perhaps someone of MarkLogic likes to comment as well?
> Kind regards,
> Geert
> Drs. G.P.H. Josten
> Consultant
> http://www.daidalos.nl/
> Daidalos BV
> Source of Innovation
> Hoekeindsehof 1-4
> 2665 JZ Bleiswijk
> Tel.: +31 (0) 10 850 1200
> Fax: +31 (0) 10 850 1199
> http://www.daidalos.nl/
> 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: woensdag 24 september 2008 23:56
>> To: ML Developer Mailing List
>> Subject: [MarkLogic Dev General] Scaffolding
>> Hi all,
>> Our website translations reside in xml files, however it
>> became rather tedious to edit and re-load a local file xml
>> file into MarkLogic for every small change.
>> I've put together an xml scaffolding written in xquery.  If
>> you've never heard of a software scaffolding before, it
>> simply allows temporary front-end access to back-end data,
>> while the real front-end is still under development.  There
>> are many sql-based scaffolding apps made for php and other
>> web-based languages.
>> The basic idea here is: provide a simple interface to quickly
>> browse and edit xml documents with a web browser.
>> WARNING: Scaffolding is still very much under construction,
>> in fact there are still data-destroying bugs present!  Don't
>> use Scaffolding on anything other than throwaway/test xml documents!
>> To try it out, grab the attached scaffolding.xqy file, drop
>> it into an http app server, and point your browser to its location.
>> There is a bug I'm still stumped on, and would appreciate
>> some help with.  When saving a document containing attributes
>> which are part of an element which has only text-node
>> children (ex. <sign width="10"
>> height="5">hello</sign>), those attributes vanish (ex.
>> <sign>hello</sign>).  However, if you grab the command from
>> the log (line 253) and execute it standalone (in CQ, for
>> example), given the same document, the attributes are saved
>> successfully.  Attributes which are part of an element which
>> has only element-node children are also saved successfully.
>> If you do attempt to browse through the source, I'll
>> apologize now about the lack of comments and general
>> messiness, it was put together in half a day last week.  To
>> an xquery vet, however, it should be at least somewhat intuitive.
>> I'd love to get ANY kind of feedback you've got.
>> Thanks,
>> Eric
> _______________________________________________
> General mailing list
> General at developer.marklogic.com
> http://xqzone.com/mailman/listinfo/general

More information about the General mailing list