如何在Oracle PLSQL中获得自动关闭的xml标记?

时间:2017-06-08 15:36:08

标签: xml oracle xmltype xml-generation

请求的输出应如下:

<Consignment id="123" date="2017-06-08">
    <Box id="321" />
</Consignment>

<box>标记应该如上所述自动关闭。

我使用以下代码:

SELECT XMLELEMENT( "Consignment", XMLATTRIBUTES('123' AS "id",sysdate AS "date" ),
            XMLELEMENT( "Box", xmlattributes( '321' as "id" ))     
                 ).getstringval() as xxx FROM DUAL;

但它始终返回以下结果(标记<box>有一个单独的结束标记</box>):

<Consignment id="123" date="2017-06-08">
    <Box id="321"></Box>
</Consignment>

如何让上述<box>代码自行关闭?

2 个答案:

答案 0 :(得分:2)

如果您只需要使用&#34; box&#34;,那么您可以使用:

SELECT REPLACE(XMLELEMENT( "Consignment", XMLATTRIBUTES('123' AS "id",sysdate AS "date" ),
            XMLELEMENT( "Box", xmlattributes( '321' as "id" ))     
                 ).getstringval(),'></Box>',' />') as xxx FROM DUAL;

如果您有其他需要以这种方式处理的标记,则需要使用相同的逻辑来使用REGEXP_REPLACE。

从语义上讲,两种形式都代表完全相同的数据,这就是为什么你不能做你想做的事情而且容易做到的事情。给XML生成器一些参数(为什么你不应该首先这样做!)。

答案 1 :(得分:2)

如果您通过the XMLSerialize() function传递生成的XML片段/文档,并指定INDENTNO INDENT,则空标记将转换为自我关闭。 (未指定要么保持不变)。

SELECT XMLSerialize(CONTENT
    XMLELEMENT( "Consignment", XMLATTRIBUTES('123' AS "id",sysdate AS "date" ),
      XMLELEMENT( "Box", xmlattributes( '321' as "id" ))
  ) as VARCHAR2(4000) INDENT) as xxx FROM DUAL;

XXX                                                                             
--------------------------------------------------------------------------------
<Consignment id="123" date="2017-06-08">
  <Box id="321"/>
</Consignment>

或没有格式化:

SELECT XMLSerialize(CONTENT
    XMLELEMENT( "Consignment", XMLATTRIBUTES('123' AS "id",sysdate AS "date" ),
      XMLELEMENT( "Box", xmlattributes( '321' as "id" ))
  ) as VARCHAR2(4000) NO INDENT) as xxx FROM DUAL;

XXX                                                                             
--------------------------------------------------------------------------------
<Consignment id="123" date="2017-06-08"><Box id="321"/></Consignment>

您的问题显示输出为缩进,但您提供的代码不会缩进,因此不确定您实际需要哪些代码。

我已根据您对VARCHAR2的使用情况使用getStringVal作为数据类型,如果您知道尺寸,则可以将其设为较小 - 或切换为CLOB你不知道,或者知道VARCHAR2可能太大了。