XQuery 在使用 CDATA 更新节点期间将<>更改为'<'和'>'



我在更新oracle数据库中的大型XML文件时遇到了问题。

这个XML描述了数据库结构,我必须更新很多节点。我遇到的问题是,当我必须更新节点中的<![CDATA[...]]>时。我常用的查询是这样的:

 UPDATE XML_TABLE set XML_TABLE.xml =
  (select XMLQuery('copy $tmp := . modify
     (for $i in $tmp/MODEL/ERD/ENTITIES/ENTITY[upper-case(NAME) = "SOME_TABLE"]NOTES/text()  
      return replace value of node $i with $p0) 
            return $tmp'
           PASSING x.xml, '<![CDATA[ new text value ]]>' as "p0" RETURNING CONTENT) FROM XML_TABLE x )

我选择这种查询的原因是我可以让它一次更新多个节点:

select xmlquery(' copy $tmp := . modify 
                  ((for $j in $tmp/MOD (...)return insert node $p1 as last into $j),
                   (for $j in $tmp/MODEL(...)return insert node $p2 as last into $j),
                   (for $j in $tmp/MODEL(...)return insert node $p3 as last into $j))
                   return $tmp'
                   passing x.xml, 'whatever1' as "p1",
                                  'something1' as "p2",
                                  'sth2' as "p3"                    
                   returning content
                   )
From XML_TABLE x

不幸的是,我不能用<![CDATA[...]]>更新节点。将"<"one_answers">"符号替换为"&lt;"one_answers"&gt;"。我不能封装CDATA在XMLTYPE: XMLTYPE('<![CDATA[...]]>),因为我得到一个错误。

我可以使用已弃用的函数UPDATEXML(),但是我需要XPath 1.0中不支持的upper-case()函数,而且translate()方法很难看,我不知道在这种情况下如何使用它。当然,我不能保证它不会翻译<>到&lt; &gt; .

你知道有什么方法可以帮我解决这个问题吗?

好的,我使用了一个UPDATEXML()函数,它对我有用。它不会改变<>到&lt; &gt;,但不支持upper-case()的任何功能(仅支持translate())。但是我有能力稍微重建我的程序,现在,我不需要做字符串比较。但是,这不是问题的答案,所以我将把它留作未解决。

CDATA不替换任何东西。它只是一个XML结构,允许您编写纯文本,而不必转义标记。这只是语法上的糖,并且总是等同于将其内容写成文本并进行适当的转义。例如:

<p><![CDATA[Use <p>Hello.</p> to write a paragraph.]]></p>

总是等价于:

<p>Use &lt;p>Hello.&lt;/p> to write a paragraph.</p>

当您手工编写文本中包含大量标记的XML文档(如文章)时(如关于XML的文章,在文本中包含XML示例),这有时会很有用。

一旦被解析,CDATA就不会以任何方式被"记录"。一旦传递给XQuery,上述两个示例将产生完全相同的结果(如果将文本复制到输出,则很可能包含&lt;转义字符)。