如何在 Oracle PLSQL 中获取自闭合 xml 标签?

Posted

技术标签:

【中文标题】如何在 Oracle PLSQL 中获取自闭合 xml 标签?【英文标题】:How to get a self-closing xml tag in Oracle PLSQL? 【发布时间】:2017-11-10 10:08:15 【问题描述】:

请求的输出应该如下:

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

&lt;box&gt; 标签应该像上面那样自动关闭。

我正在使用以下代码:

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

但它总是返回以下结果(标签&lt;box&gt; 有一个单独的结束标签&lt;/box&gt;):

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

如何让上面的&lt;box&gt;标签自闭?

【问题讨论】:

REPLACE 是你的朋友:) &lt;Box id="321"&gt;&lt;/Box&gt;&lt;Box id="321" /&gt; 相同。为什么喜欢改大纲? 正如 Wernfried 所说,这两种格式是没有文本子元素的 Box 元素的替代序列化。任何 XML 处理器都不应该关心它收到的是哪个版本。通常,当某些下游进程尝试使用字符串操作技术(正则表达式、替换等)来操作序列化的 XML 时,通常会出现这些问题,这总是一个坏主意,通常会以眼泪结束,或者论坛上出现不必要的问题,例如堆栈溢出。 【参考方案1】:

如果您只需要使用“box”来执行此操作,那么您可以使用:

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 生成器提供的某些参数“轻松”做您想做的事情(以及为什么您可能不应该在第一个地方!)。

【讨论】:

【参考方案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>

您的问题将输出显示为缩进,但您提供的代码没有缩进,因此不确定您真正想要哪个。

根据您对getStringVal 的使用,我已将VARCHAR2 用于数据类型,如果您知道大小,则可以将其缩小 - 如果您不知道或不知道,则切换到CLOB VARCHAR2 可能太大了。

【讨论】:

以上是关于如何在 Oracle PLSQL 中获取自闭合 xml 标签?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 PLSQL 中获取 livesql.oracle.com 中的用户输入

(非无效)自闭合标签在 HTML5 中有效吗?

如何在动态 sql (ORACLE PLSQL) 中获取局部临时变量中的计数 (*) 值

Oracle APEX 交互式网格:如何使用 PLSQL 访问内容?

可以使用自闭合 DIV 标签吗? [复制]

自闭合标签-主动闭合标签-meta-link标签