如何在Oracle中生成具有空字符串作为属性的XML数据

时间:2015-09-03 15:49:05

标签: sql xml oracle

我想使用Oracle的XML文档生成支持功能生成一个XML元素,如下所示

<Example Attr=""></Example>

Attr是元素Example的一个属性,其值为空字符串“”。

当我尝试使用Oracle的XML函数生成XML元素时,我无法生成一个XML元素,该元素的属性值为空字符串。

select XMLELEMENT("hello", xmlattributes('' as  "Max"))  from  dual

上述查询的结果是

<hello></hello>

注意:Max属性的单引号之间没有空格。

但我的要求是

<hello Max=""></hello>     -- there is no space between the double quotes.

有办法做到这一点吗?

4 个答案:

答案 0 :(得分:4)

如您所知,对于XMLAtttribute "if the value_expr is null, then no attribute is created for that value expression"

您可以使用InsertChildXML解决此问题,但它并不是非常漂亮:

select insertchildxml(xmlelement("hello"), '/hello', '@Max', null) from dual;

INSERTCHILDXML(XMLELEMENT("HELLO"),'/HELLO','@MAX',NULL)                       
--------------------------------------------------------------------------------
<hello Max=""/>

...正如您所看到的那样,它会折叠一个空节点,但如果您希望这看起来与您所展示的完全相同,那么这只是一个潜在的问题 - 它仍然是有效的XML。如果你真的需要,可以an even uglier way around that

这也暗示了@ smnbbrv的replace

的替代品
select updatexml(xmlelement("hello", xmlattributes('$$IMPOSSIBLE-VALUE$$' as  "Max")),
  '/hello[@Max="$$IMPOSSIBLE-VALUE$$"]/@Max', null) from dual;

UPDATEXML(XMLELEMENT("HELLO",XMLATTRIBUTES('$$IMPOSSIBLE-VALUE$$'AS"MAX")),'/HEL
--------------------------------------------------------------------------------
<hello Max=""/>

如果你的最大属性值来自数据可能会更容易,因为你可以将它NVL到不可能的值。我真的不喜欢使用魔法值。

答案 1 :(得分:3)

如何将属性值设置为某个不可能的值,然后将其替换为您需要的值(因此,在您的情况下为空字符串)?

select replace(
  XMLELEMENT("hello", xmlattributes('$$IMPOSSIBLE-VALUE$$' as  "Max")).getStringVal(),
  '$$IMPOSSIBLE-VALUE$$'
)
from  dual;

我认为你最终还是需要字符串值,所以即使这个XMLELEMENT只是问题的一个例子并且你生成了一个biiiig XML,你仍然可以先生成它然后,最后,用一个命令替换所有值,如上所示。

答案 2 :(得分:0)

我正在使用这种方法(您编写源属性而不是“null”)。这样,您就不必搜索一些总体上不可能的值,这对于该属性来说已经足够了。

select replace(XMLELEMENT("hello", xmlattributes(nvl(null,' ') as "Max")).getstringval(), 'Max=" "', 'Max=""') from dual

答案 3 :(得分:0)

我使用updatexml()类似于A. Poole的例子来创建一个空字符串

set serveroutput on
 DECLARE
   xa xmltype;
   xb xmltype;
 BEGIN
   xa  := xmltype('<surfbreaks>'||
     '<break lineNum="0" recordtype="empty">d street </break>'||
     '<break lineNum="0" recordtype="empty">recordtype="empty" </break>'||
     '</surfbreaks>');

  dbms_output.put_line ('Before:');
  dbms_output.put_line (xa.getclobval);

  select UPDATEXML(xa, '//@recordtype', '') into xb from dual;
  dbms_output.put_line ('After:');
  dbms_output.put_line (xb.getclobval);
END; /