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