Consider the following three statements.
1:
XMLSERIALIZE(DOCUMENT XMLQUERY(q'^
copy $i := $doc modify (
for $j in $i/tdfmt/text()[1]
return
insert node ( $text, $br, '
' ) before $j
)
return $i
^'
PASSING
XMLTYPE(OIT.INFTXT) AS "doc",
LENGTH(EXTRACTVALUE(XMLTYPE(OIT.INFTXT),'tdfmt/text()[1]')) AS "len",
'NEW TEXT TO INSERT' AS "text",
XMLTYPE('<br/>') AS "br"
RETURNING CONTENT) AS CLOB INDENT SIZE=4 )
AS NEW_INFTXT_A
2:
XMLSERIALIZE(DOCUMENT XMLQUERY(q'^
copy $i := $doc modify (
for $j in $i/*
return
insert node ( $text, $br, '
' ) into $j
)
return $i
^'
PASSING
XMLTYPE(OIT.INFTXT) AS "doc",
LENGTH(EXTRACTVALUE(XMLTYPE(OIT.INFTXT),'tdfmt/text()[1]')) AS "len",
'NEW TEXT TO INSERT' AS "text",
XMLTYPE('<br/>') AS "br"
RETURNING CONTENT) AS CLOB INDENT SIZE=4 )
AS NEW_INFTXT_B
3:
XMLSERIALIZE(DOCUMENT XMLQUERY(q'^
if ($len>0)
then
copy $i := $doc modify (
for $j in $i/tdfmt/text()[1]
return
insert node ( $text, $br, '
' ) before $j
)
return $i
else
copy $i := $doc modify (
for $j in $i/*
return
insert node ( $text, $br, '
' ) into $j
)
return $i
^'
PASSING
XMLTYPE(OIT.INFTXT) AS "doc",
LENGTH(EXTRACTVALUE(XMLTYPE(OIT.INFTXT),'tdfmt/text()[1]')) AS "len",
'NEW TEXT TO INSERT' AS "text",
XMLTYPE('<br/>') AS "br"
RETURNING CONTENT) AS CLOB INDENT SIZE=4 )
AS NEW_INFTXT1
The idea is to switch between 1 and 2 depending on the length of my node.
In the output of 3, I noticed that the xml declaration <?xml version="1.0"?>
is omitted while with 1 and 2 it is present. Any idea why adding an if then else
statement would cause this behaviour and what I should to to prevent the declaration form being dropped.
Not sure why it has that effect, but you can avoid it by putting the if
within the modify
:
XMLSERIALIZE(DOCUMENT XMLQUERY(q'^
copy $i := $doc modify (
if ($len>0)
then
for $j in $i/tdfmt/text()[1]
return
insert node ( $text, $br, '
' ) before $j
else
for $j in $i/*
return
insert node ( $text, $br, '
' ) into $j
)
return $i
^'
PASSING
XMLTYPE(OIT.INFTXT) AS "doc",
LENGTH(EXTRACTVALUE(XMLTYPE(OIT.INFTXT),'tdfmt/text()[1]')) AS "len",
'NEW TEXT TO INSERT' AS "text",
XMLTYPE('<br/>') AS "br"
RETURNING CONTENT) AS CLOB INDENT SIZE=4 )
AS NEW_INFTXT1
You can also test for the existence of the node in the FLWOR, rather than passing $len
in:
XMLSERIALIZE(DOCUMENT XMLQUERY(q'^
copy $i := $doc modify (
if (exists($i/tdfmt/text()[1]))
then
for $j in $i/tdfmt/text()[1]
return insert node ( $text, $br, $newline ) before $j
else
for $j in $i/*
return insert node ( $text, $br, $newline ) into $j
)
return $i
^'
PASSING
XMLTYPE(OIT.INFTXT) AS "doc",
'NEW TEXT TO INSERT' AS "text",
XMLTYPE('<br/>') AS "br",
CHR(10) AS "newline"
RETURNING CONTENT) AS CLOB INDENT SIZE=4 )
AS NEW_INFTXT1
(also changed to pass $newline
in as shown in a previous answer, just because I think it looks neater *8-)