Hi Christian --

Or I could just be a simple creature and use
let $test as element(root) :=
<root>
  <content>{serialize(
    <div>words <b>bold</b> words</div>
    )}
  </content>
</root>

return file:write('/home/graydon/test2.xml',
$test,
map { "method": "xml", "cdata-section-elements": "content"})

Which gives

<root>
  <content><![CDATA[<div>words <b>bold</b> words</div>]]></content>
</root>

(Your solution is considerably more elegant but would be much trickier to use the actual case.)

Thank you!

On Wed, Aug 26, 2020 at 5:12 PM Christian Grün <christian.gruen@gmail.com> wrote:
Hi Graydon,

I can’t say much about serialization in XSLT, but the serialization of
CDATA sections in XQuery is indeed focused on text nodes [1]:

  “The cdata-section-elements parameter contains a list of expanded
QNames. If the expanded QName of the parent of a text node is a member
of the list, then the text node MUST be output as a CDATA section,
[…].”

If you want to serialize the descendants of specific elements as text,
you could try this:

declare option output:method 'xml';
declare option output:cdata-section-elements 'div';

let $test := <root>
  <content>
     <div>words <b>bold</b> words</div>
  </content>
</root>
return $test update {
  .//div ! (replace value of node . with serialize(node()))
}

Hope this helps,
Christian

[1] https://www.w3.org/TR/xslt-xquery-serialization-31/#XML_CDATA-SECTION-ELEMENTS



On Wed, Aug 26, 2020 at 11:00 PM Graydon Saunders <graydonish@gmail.com> wrote:
>
> Using 9.4.2 and 943-20200826.181852 I get the same result:
>
> let $test as element(root) :=
> <root>
>   <content>
>     <div>words</div>
>   </content>
> </root>
>
> return file:write('/home/graydon/test2.xml',
> $test,
> map { "method": "xml", "cdata-section-elements": "content"})
>
> does not work, in the sense that no CDATA block is created.
>
> let $test as element(root) :=
> <root>
>   <content>
>     <div>words</div>
>   </content>
> </root>
>
> return file:write('/home/graydon/test2.xml',
> $test,
> map { "method": "xml", "cdata-section-elements": "div"})
>
> does work, in the sense that the text contents of div gets wrapped in CDATA.
>
> If I try
> let $test as element(root) :=
> <root>
>   <content>
>     <div>words <b>bold</b> words</div>
>   </content>
> </root>
>
> return file:write('/home/graydon/test2.xml',
> $test,
> map { "method": "xml", "cdata-section-elements": "div"})
>
> I get
>
> <root>
>   <content>
>     <div><![CDATA[words ]]><b>bold</b><![CDATA[ words]]></div>
>   </content>
> </root>
>
> which makes me think that only text node children of the element get wrapped in a CDATA block.
>
> I would expect (from the way XSLT processors usually behave) that the content of an element with element children would be serialized into a CDATA block.  Am I confused?  Is this a bug? is there a  more appropriate way to declare the contents of the content element a CDATA block?
>
> Thanks!
> Graydon