如何使用所有列作为属性和行作为名为 <ROW> 的 XML 标签生成 XML

How to generate XML using all the columns as attributes and rows as XML tag named <ROW>

要求:您好,我需要从 CTE 生成的结果中生成 XML。每行应由一个新的 XML 标记表示,所有列值都是其 XML 属性。

条件:CTE 中的查询是动态的,因此它生成的名称、编号和列不能事先知道。

为了生成 XML 我目前 运行 CTE 中的查询并在 XMLATTRIBUTES() 函数中输入每个列名,如下例所示:-

with cte as(
select 'john' as name_,
'2021' as dept,
'26' as age
FROM dual
)
SELECT
   XMLELEMENT("ROW", XMLAGG( XMLELEMENT("ROW", XMLATTRIBUTES( name_,dept,age ) ) ) ) 
FROM
   cte;

请提出一种无需键入所有列名即可包含 CTE 查询生成的所有列的方法

您可以使用 dbms_xmlgen 生成您的 CTE 的 XML 版本;小技巧是使用 cursor() 函数动态创建一个上下文,形成一个引用游标:

with cte as(
select 'john' as name_,
'2021' as dept,
'26' as age
FROM dual
)
SELECT
   dbms_xmlgen.getxmltype(dbms_xmlgen.newcontext(cursor(select * from cte)))
from dual;

生成:

<ROWSET>
 <ROW>
  <NAME_>john</NAME_>
  <DEPT>2021</DEPT>
  <AGE>26</AGE>
 </ROW>
</ROWSET>

然后即兴this answer,可以将列节点转换为属性:

with cte as(
select 'john' as name_,
'2021' as dept,
'26' as age
FROM dual
)
SELECT
   dbms_xmlgen
     .getxmltype(dbms_xmlgen.newcontext(cursor(select * from cte)))
     .transform(xmltype('<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="ROWSET">
    <ROWSET>
      <xsl:apply-templates/>
    </ROWSET>
  </xsl:template>

  <xsl:template match="ROW">
    <ROW>
      <xsl:for-each select="*">
        <xsl:attribute name="{name()}">
          <xsl:value-of select="text()"/>
        </xsl:attribute>

      </xsl:for-each>
    </ROW>
  </xsl:template>
</xsl:stylesheet>'))
from dual;

这给你:

<ROWSET>
 <ROW NAME_="john" DEPT="2021" AGE="26"></ROW>
</ROWSET>

我将根节点保留为 rowset,但如果您真的希望根节点和内部节点都被称为 row,您可以在 XLST 文档中更改它。如果您不希望结果作为 XMLType.

,您可以添加 tostringval()toclobval() 调用

db<>fiddle