Oracle:将树结构转换为XML

时间:2013-04-22 11:29:58

标签: xml oracle hierarchical-data

我有一个简单的树结构,其中子元素连接到父元素,我需要转换为XML。

目前,我使用递归函数调用来实现它(即检索给定元素的子元素),这似乎不是最聪明的方法。涉及CONNECT BY PRIOR的语句将输出结果,但我不知道如何将其转换为XML。

我的简化数据结构:

CREATE TABLE ENTRY
  (
    "ID"        NUMBER(10,0) NOT NULL ENABLE,
    "PARENT_ID" NUMBER(10,0),
    "TAG"       VARCHAR2(1000 CHAR)
  )

期望的输出:

<?xml version="1.0" encoding="UTF-8"?>
<entries>
    <entry>
        <tag>parent A</tag>
        <entries>
            <entry>
                <tag>child A-1</tag>
                <entries>
                    <entry>
                        <tag>grandchild A-1</tag>
                    </entry>
                </entries>
            </entry>
            <entry>
                <tag>child A-2</tag>
            </entry>
        </entries>
    </entry>
    <entry>
        <tag>bla parent B</tag>
        <entries>
            <entry>
                <tag>child B-1</tag>
            </entry>
        </entries>
    </entry>
</entries>

我正在寻找一个单独的SELECT语句来完成这项工作:)

感谢您的任何建议!

1 个答案:

答案 0 :(得分:0)

您可以使用递归PL / SQL函数:

SQL> CREATE OR REPLACE FUNCTION getXMLChildren(p_parent_id NUMBER)
  2     RETURN XMLTYPE IS
  3     l XMLTYPE;
  4  BEGIN
  5     SELECT xmlelement("entries",
  6                       xmlagg(xmlelement("entry",
  7                                         xmlelement("tag", tag),
  8                                         getXMLChildren(ID))))
  9       INTO l
 10       FROM ENTRY
 11      WHERE (p_parent_id IS NOT NULL AND parent_ID = p_parent_id)
 12         OR (p_parent_id IS NULL AND parent_id IS NULL) --
 13      HAVING COUNT(*) > 0;
 14     RETURN l;
 15  END;
 16  /

Function created

此函数构建第一级,然后在子级上调用自己:

SQL> select XMLSERIALIZE(document getXMLChildren(NULL)
  2                      as CLOB INDENT SIZE = 2) xml
  3    from dual;

XML
--------------------------------------------------------------------------------
<entries>
  <entry>
    <tag>bla parent</tag>
    <entries>
      <entry>
        <tag>bla child 1</tag>
        <entries>
          <entry>
            <tag>bla grandchild1</tag>
          </entry>
        </entries>
      </entry>
      <entry>
        <tag>bla child 2</tag>
      </entry>
    </entries>
  </entry>
</entries>