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)
} {
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: [EMAIL PROTECTED]
[mailto:[EMAIL PROTECTED] 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
[email protected]
http://xqzone.com/mailman/listinfo/general