Discussion:
[xquery-talk] How do I insert a node as first element within a for loop?
Alex Muir
2016-07-06 09:10:11 UTC
Permalink
Greetings,

Running in Basex I get the following error:

XUST0001 <https://www.w3.org/TR/xquery-update-10/#ERRXUST0001> element
constructor: no updating expression allowed.

When trying to insert *insert nodes test as first into $c*

I feel like my code is following the examples
<http://www.xmlmind.com/tutorials/XQueryUpdate/> I see online although
clearly I've got something wrong.

How do I insert a node with a for loop?

declare namespace db="http://basex.org/modules/db";
declare namespace file="http://expath.org/ns/file";
declare variable $form13FFileNumber as xs:string external;

let $data := db:open('13F')//data[contains(edgarSubmission/formData/coverPage/form13FFileNumber,$form13FFileNumber)]

let $fields :=

<form13FFile>
{
for $c in $data return
insert nodes <b4>test</b4> as first into $c
}
</form13FFile>

return file:write(concat('../OUT/' , $form13FFileNumber , '.xml'), $fields)

To be more clear my xml looks something like

<data>
<first_Child>text</first_child>
</data>
<data>
<first_Child>text</first_child>
</data>

and I would like it to adjust to

<form13FFile>
<data>
<b4>test</b4>
<first_Child>text</first_child>
</data>
<data>
<b4>test</b4>
<first_Child>text</first_child>
</data>
</form13FFile>



Regards
Alex
tech.jahtoe.com
bafila.jahtoe.com
Ghislain Fourny
2016-07-06 09:19:48 UTC
Permalink
Hi Alex,

You can either use a query, or updates. Your query mixes both, which is why
you are getting an error, as updates can't be nested in expressions that
produce items.

In your case though, since you need to modify the top-level, a query makes
most sense, and the good news is it's really simple.

...
let $fields :=
<form13FFile>{
$data
}</form13FFile>
...

Then you can replace the file with the results of the query as you do with
file:write.

If you really want to update, you can do something like:

replace node $data with
<form13FFile>{
$data
}</form13FFile>

but then you can't use the file:write machinery and need to rely on the
underlying engine to do the edit in place.

In the more general case where you need to edit plenty of places in your
document, you can use the copy-modify-return expression. It's very handy to
create an updated copy.

I hope it helps!

Kind regards,
Ghislain
Post by Alex Muir
Greetings,
XUST0001 element constructor: no updating expression allowed.
When trying to insert insert nodes test as first into $c
I feel like my code is following the examples I see online although
clearly I've got something wrong.
Post by Alex Muir
How do I insert a node with a for loop?
declare namespace db="http://basex.org/modules/db";
declare namespace file="http://expath.org/ns/file";
declare variable $form13FFileNumber as xs:string external;
let $data :=
db:open('13F')//data[contains(edgarSubmission/formData/coverPage/form13FFileNumber,$form13FFileNumber)]
Post by Alex Muir
let $fields :=
<form13FFile>
{
for $c in $data return
insert nodes <b4>test</b4> as first into $c
}
</form13FFile>
return file:write(concat('../OUT/' , $form13FFileNumber , '.xml'), $fields)
To be more clear my xml looks something like
<data>
<first_Child>text</first_child>
</data>
<data>
<first_Child>text</first_child>
</data>
and I would like it to adjust to
<form13FFile>
<data>
<b4>test</b4>
<first_Child>text</first_child>
</data>
<data>
<b4>test</b4>
<first_Child>text</first_child>
</data>
</form13FFile>
Regards
Alex
tech.jahtoe.com
bafila.jahtoe.com
_______________________________________________
http://x-query.com/mailman/listinfo/talk
Ghislain Fourny
2016-07-06 09:22:44 UTC
Permalink
Hi Alex,

Me again. I read through your expected result too fast and missed the b4
part :-)

So indeed you need a copy modify:

...
let $fields :=
<form13FFile>
{
for $c in $data
return
copy $new-node := $c
modify insert nodes <b4>test</b4> as first into $new-node
return $new-node
}
</form13FFile>
...

I hope I got it right this time!

Kind regards,
Ghislain
Post by Ghislain Fourny
Hi Alex,
You can either use a query, or updates. Your query mixes both, which is
why you are getting an error, as updates can't be nested in expressions
that produce items.
Post by Ghislain Fourny
In your case though, since you need to modify the top-level, a query
makes most sense, and the good news is it's really simple.
Post by Ghislain Fourny
...
let $fields :=
<form13FFile>{
$data
}</form13FFile>
...
Then you can replace the file with the results of the query as you do
with file:write.
Post by Ghislain Fourny
replace node $data with
<form13FFile>{
$data
}</form13FFile>
but then you can't use the file:write machinery and need to rely on the
underlying engine to do the edit in place.
Post by Ghislain Fourny
In the more general case where you need to edit plenty of places in your
document, you can use the copy-modify-return expression. It's very handy to
create an updated copy.
Post by Ghislain Fourny
I hope it helps!
Kind regards,
Ghislain
Post by Alex Muir
Greetings,
XUST0001 element constructor: no updating expression allowed.
When trying to insert insert nodes test as first into $c
I feel like my code is following the examples I see online although
clearly I've got something wrong.
Post by Ghislain Fourny
Post by Alex Muir
How do I insert a node with a for loop?
declare namespace db="http://basex.org/modules/db";
declare namespace file="http://expath.org/ns/file";
declare variable $form13FFileNumber as xs:string external;
let $data :=
db:open('13F')//data[contains(edgarSubmission/formData/coverPage/form13FFileNumber,$form13FFileNumber)]
Post by Ghislain Fourny
Post by Alex Muir
let $fields :=
<form13FFile>
{
for $c in $data return
insert nodes <b4>test</b4> as first into $c
}
</form13FFile>
return file:write(concat('../OUT/' , $form13FFileNumber , '.xml'), $fields)
To be more clear my xml looks something like
<data>
<first_Child>text</first_child>
</data>
<data>
<first_Child>text</first_child>
</data>
and I would like it to adjust to
<form13FFile>
<data>
<b4>test</b4>
<first_Child>text</first_child>
</data>
<data>
<b4>test</b4>
<first_Child>text</first_child>
</data>
</form13FFile>
Regards
Alex
tech.jahtoe.com
bafila.jahtoe.com
_______________________________________________
http://x-query.com/mailman/listinfo/talk
Alex Muir
2016-07-06 09:27:48 UTC
Permalink
Hi Ghislain,

That worked!

Cheers!


Regards
Alex
tech.jahtoe.com
bafila.jahtoe.com
Post by Ghislain Fourny
Hi Alex,
Me again. I read through your expected result too fast and missed the b4
part :-)
...
let $fields :=
<form13FFile>
{
for $c in $data
return
copy $new-node := $c
modify insert nodes <b4>test</b4> as first into $new-node
return $new-node
}
</form13FFile>
...
I hope I got it right this time!
Kind regards,
Ghislain
Post by Ghislain Fourny
Hi Alex,
You can either use a query, or updates. Your query mixes both, which is
why you are getting an error, as updates can't be nested in expressions
that produce items.
Post by Ghislain Fourny
In your case though, since you need to modify the top-level, a query
makes most sense, and the good news is it's really simple.
Post by Ghislain Fourny
...
let $fields :=
<form13FFile>{
$data
}</form13FFile>
...
Then you can replace the file with the results of the query as you do
with file:write.
Post by Ghislain Fourny
replace node $data with
<form13FFile>{
$data
}</form13FFile>
but then you can't use the file:write machinery and need to rely on the
underlying engine to do the edit in place.
Post by Ghislain Fourny
In the more general case where you need to edit plenty of places in your
document, you can use the copy-modify-return expression. It's very handy to
create an updated copy.
Post by Ghislain Fourny
I hope it helps!
Kind regards,
Ghislain
Post by Alex Muir
Greetings,
XUST0001 element constructor: no updating expression allowed.
When trying to insert insert nodes test as first into $c
I feel like my code is following the examples I see online although
clearly I've got something wrong.
Post by Ghislain Fourny
Post by Alex Muir
How do I insert a node with a for loop?
declare namespace db="http://basex.org/modules/db";
declare namespace file="http://expath.org/ns/file";
declare variable $form13FFileNumber as xs:string external;
let $data :=
db:open('13F')//data[contains(edgarSubmission/formData/coverPage/form13FFileNumber,$form13FFileNumber)]
Post by Ghislain Fourny
Post by Alex Muir
let $fields :=
<form13FFile>
{
for $c in $data return
insert nodes <b4>test</b4> as first into $c
}
</form13FFile>
return file:write(concat('../OUT/' , $form13FFileNumber , '.xml'),
$fields)
Post by Ghislain Fourny
Post by Alex Muir
To be more clear my xml looks something like
<data>
<first_Child>text</first_child>
</data>
<data>
<first_Child>text</first_child>
</data>
and I would like it to adjust to
<form13FFile>
<data>
<b4>test</b4>
<first_Child>text</first_child>
</data>
<data>
<b4>test</b4>
<first_Child>text</first_child>
</data>
</form13FFile>
Regards
Alex
tech.jahtoe.com
bafila.jahtoe.com
_______________________________________________
http://x-query.com/mailman/listinfo/talk
Continue reading on narkive:
Loading...