`
wuhuizhong
  • 浏览: 681099 次
  • 性别: Icon_minigender_1
  • 来自: 中山
社区版块
存档分类
最新评论

An Easy Way to Convert a Hierarchical Query Result to XML

 
阅读更多

Consider the following classic employees table:

SQL> SELECT employee_id,
  2    manager_id,
  3    first_name,
  4    salary,
  5    hire_date
  6  FROM employees;

EMPLOYEE_ID MANAGER_ID FIRST_NAME               SALARY HIRE_DATE
----------- ---------- -------------------- ---------- ---------
        100            Steven                    24000 17-JUN-87
        101        100 Neena                     17000 21-SEP-89
        102        100 Lex                       17000 13-JAN-93
        103        102 Alexander                  9000 03-JAN-90
        104        103 Bruce                      6000 21-MAY-91
        105        103 David                      4800 25-JUN-97
        106        103 Valli                      4800 05-FEB-98
        107        103 Diana                      4200 07-FEB-99
        108        101 Nancy                     12000 17-AUG-94
        109        108 Daniel                     9000 16-AUG-94
        110        108 John                       8200 28-SEP-97
        ...



The manager_id is also an employee_id. So, we can build the following hierarchical query:

 

SQL> SELECT
  2    rpad(' ',   4 * LEVEL -1,   ' ') || first_name tree,
  3    LEVEL,
  4    employee_id,
  5    manager_id,
  6    salary,
  7    hire_date
  8  FROM employees
  9  START WITH manager_id IS NULL
 10  CONNECT BY PRIOR employee_id = manager_id
 11  ORDER siblings BY first_name;

TREE                      LEVEL EMPLOYEE_ID MANAGER_ID     SALARY HIRE_DATE
-------------------- ---------- ----------- ---------- ---------- ---------
   Steven                     1         100                 24000 17-JUN-87
       Adam                   2         121        100       8200 10-APR-97
           Alexis             3         185        121       4100 20-FEB-97
           Anthony            3         187        121       3000 07-FEB-99
           James              3         131        121       2500 16-FEB-97
           Julia              3         186        121       3400 24-JUN-98
           Laura              3         129        121       3300 20-AUG-97
           Mozhe              3         130        121       2800 30-OCT-97
           Nandita            3         184        121       4200 27-JAN-96
           TJ                 3         132        121       2100 10-APR-99
       Alberto                2         147        100      12000 10-MAR-97
       ...



Now what we want is to transform the above result set to XML. We could use DBMS_XMLGEN.getxml like this:

SQL> SELECT DBMS_XMLGEN.getxml('
  2          SELECT
  3            employee_id,
  4            manager_id,
  5            first_name,
  6            salary,
  7            hire_date
  8          FROM employees
  9          START WITH manager_id IS NULL
 10         CONNECT BY PRIOR employee_id = manager_id
 11         ORDER siblings BY first_name
 12  ') xml
 13  FROM dual;

XML
----------------------------------------------------    
<?xml version="1.0"?>
<ROWSET>
 <ROW>
  <EMPLOYEE_ID>100</EMPLOYEE_ID>
  <FIRST_NAME>Steven</FIRST_NAME>
  <SALARY>24000</SALARY>
  <HIRE_DATE>17-JUN-87</HIRE_DATE>
 </ROW>
 <ROW>
  <EMPLOYEE_ID>121</EMPLOYEE_ID>
  <MANAGER_ID>100</MANAGER_ID>
  <FIRST_NAME>Adam</FIRST_NAME>
  <SALARY>8200</SALARY>
  <HIRE_DATE>10-APR-97</HIRE_DATE>
 </ROW>
 ...
</ROWSET>



But this is not what we want. We want the hierarchical structure to be maintained in the XML output. In other words, we would like to have hierarchical XML with recursive elements.

Starting with Oracle Database 10g Release 1 (10.0.1), we can use DBMS_XMLGEN.newContextFromHierarchy like this:

SQL> SELECT XMLELEMENT
  2            ("employees",
  3             (SELECT DBMS_XMLGEN.getxmltype
  4                        (DBMS_XMLGEN.newcontextfromhierarchy
  5                            ('SELECT level,
  6                XMLElement("employee",
  7                           XMLElement("id", employee_id),
  8                           XMLElement("name", first_name),
  9                           XMLElement("salary", salary),
 10                           XMLElement("hiredate", hire_date))
 11           FROM employees
 12           START WITH manager_id is null
 13           CONNECT BY PRIOR employee_id = manager_id
 14           ORDER SIBLINGS BY first_name'))
 15                FROM DUAL)) xmldoc
 16    FROM DUAL;

XMLDOC
-----------------------------------------------------------------------
<employees>
  <employee>
    <id>100</id>
    <name>Steven</name>
    <salary>24000</salary>
    <hiredate>1987-06-17</hiredate>
    <employee>
      <id>121</id>
      <name>Adam</name>
      <salary>8200</salary>
      <hiredate>1997-04-10</hiredate>
      <employee>
        <id>185</id>
        <name>Alexis</name>
        <salary>4100</salary>
        <hiredate>1997-02-20</hiredate>
      </employee>
    </employee>
    ...
</employees>



And that’s what we want.

Here is what the documentation says about the DBMS_XMLGEN.newContextFromHierarchy function:

newContextFromHierarchy (queryString IN VARCHAR2) RETURN ctxHandle;

Parameter: queryString (IN) – the query string, the result of which must be converted to XML. The query is a hierarchical query typically formed using a CONNECT BY clause, and the result must have the same property as the result set generated by a CONNECT BY query. The result set must have only two columns, the level number and an XML value. The level number is used to determine the hierarchical position of the XML value within the result XML document.

Returns: Context handle. Call this function first to obtain a handle that you can use in the getXML() and other functions to get a hierarchical XML with recursive elements back from the result.

Since the function returns a context handle, it is a good practice to close the context to release all resources associated with that context, including the SQL cursor and bind and define buffers, and so on. This can be done using the procedure DBMS_XMLGEN.closeContext and requires the use of PL/SQL:

SQL> CREATE TABLE xml_documents OF  XMLTYPE
  2  /

Table created.

SQL> DECLARE
  2     qryctx DBMS_XMLGEN.ctxhandle;
  3  BEGIN
  4     qryctx :=
  5        DBMS_XMLGEN.newcontextfromhierarchy
  6           ('SELECT level,
  7                XMLElement("employee",
  8                           XMLElement("id", employee_id),
  9                           XMLElement("name", first_name),
 10                           XMLElement("salary", salary),
 11                           XMLElement("hiredate", hire_date))
 12           FROM employees
 13           START WITH manager_id is null
 14           CONNECT BY PRIOR employee_id=manager_id
 15           ORDER SIBLINGS BY first_name');
 16
 17     INSERT INTO xml_documents
 18        SELECT XMLELEMENT ("emloyees", DBMS_XMLGEN.getxmltype (qryctx))
 19          FROM DUAL;
 20
 21     DBMS_XMLGEN.closecontext (qryctx);
 22  END;
 23  /

PL/SQL procedure successfully completed.

SQL> SELECT sys_nc_rowinfo$
  2    FROM xml_documents
  3  /

SYS_NC_ROWINFO$
------------------------------------------------------------------------------
<employees>
  <employee>
    <id>100</id>
    <name>Steven</name>
    <salary>24000</salary>
    <hiredate>1987-06-17</hiredate>
    <employee>
      <id>121</id>
      <name>Adam</name>
      <salary>8200</salary>
      <hiredate>1997-04-10</hiredate>
      <employee>
        <id>185</id>
        <name>Alexis</name>
        <salary>4100</salary>
        <hiredate>1997-02-20</hiredate>
      </employee>
    </employee>
    ...
</employees>



A couple of notes:

  • The XMLType datatype was first introduced in Oracle Database 9i Release 1 (9.0.1)

  • Oracle XML DB is a feature of the Oracle Database. It provides a high-performance, native XML storage and retrieval technology. You can verify that XML DB has been installed by simply running the SQL below:

    SQL> SELECT comp_name
      2    FROM dba_registry
      3  WHERE comp_name LIKE '%XML%';

    COMP_NAME
    ------------------------------------
    Oracle XML Database

Sources and Resources:

Related articles:

 

from: http://awads.net/wp/2007/02/20/an-easy-way-to-convert-a-hierarchical-query-result-to-xml/

分享到:
评论

相关推荐

    MicroMenu(AVR)

    MicroMenu provides an easy-to-use hierarchical menu interface for AVR firmware written in the C language. It was written as a way to teach myself linked-lists, and I've cleaned it up and made it ...

    A Hierarchical Neural Autoencoder for Paragraphs and Documents

    - **层次神经自编码器**(Hierarchical Neural Autoencoder)是一种深度学习模型,它通过多层次结构来处理自然语言文本。 - **段落与文档**是该模型的主要处理对象。这意味着该模型旨在理解和表示包含多个句子的段落...

    Hierarchical organization and structural flexibility

    often semi- crystalline arrays and are assembled into highly organized multilamellar systems, an organization warranting a substantial degree of stability. At the same time, they exhibit remarkable ...

    OrionA Hybrid Hierarchical Control Plane of.pdf

    address the two issues, we propose Orion, a hybrid hierarchical control plane for large-scale networks. Orion can effectively reduce the computational complexity growth of SDN control plane from super...

    DBSCAN.rar_DBSCAN_birch cluster_clustering_hierarchical cluster_

    BIRCH (balanced iterative reducing and clustering using hierarchies) is an unsupervised data mining algorithm used to perform hierarchical clustering over particularly large data-sets. An advantage of...

    Conv-DBN for Scalable Unsupervised Learning of Hierarchical Representations

    layers in a probabilistically sound way. Our experiments show that the algorithm learns useful high-level visual features, such as object parts, from unlabeled images of objects and natural scenes. We...

    Google C++ Style Guide(Google C++编程规范)高清PDF

    You can declare functions in a way that allows the compiler to expand them inline rather than calling them through the usual function call mechanism. Pros: Inlining a function can generate more ...

    VB编程资源大全(英文源码 其它)

    "This technique allows a program to save hierarchical information like the data in a TreeView in a way that is easy to understand."&lt;END&gt;&lt;br&gt;11 , OLE.zip Demonstrates the use of OLE.&lt;END&gt;&lt;br&gt;12 , ...

    hierarchical

    ### 层次狄利克雷过程 (Hierarchical Dirichlet Process, HDP) #### 概述 层次狄利克雷过程(Hierarchical Dirichlet Process, HDP)是一种非参数贝叶斯模型,用于处理涉及多组数据的聚类问题。在HDP中,每组数据...

    TreeGX

    At a glance connections can be identified, paths discovered and data relationships grasped all in an easy to use format. TreeGX will allow you to present hierarchical data in new visually engaging ...

    外文翻译 stus MVC

    The purpose of the Action is to "Convert the interface of a class into another interface the clients expect. Adapter lets classes work together that couldn_t otherwise because of incompatibility ...

    Coherent Hierarchical Culling:Hardware Occlusion Queries Made Useful

    We present a simple but powerful algorithm for optimizing the usage of hardware occlusion queries in arbitrary complex scenes. Our method minimizes the number of issued queries and reduces the delays ...

    CHAMELEON A Hierarchical Clustering Algorithm :变色龙的层次聚类算法.ppt

    CHAMELEON A Hierarchical Clustering Algorithm :变色龙的层次聚类算法.ppt

    2021-2022计算机二级等级考试试题及答案No.17518.docx

    7. InputStreamReader is a Java class used to convert a byte stream (InputStream) into a character stream (Reader), facilitating the reading of text data in different character encodings. 8. In Java, ...

    free mind

    &lt;br&gt;A mind mapper, and at the same time an easy-to-operate hierarchical editor with strong emphasis on folding. These two are not really two different things, just two different descriptions of a ...

    An Introduction to IMS

    就是这本书 http://www.ibmpressbooks.com/bookstore/product.asp?isbn=0131856715

    Hierarchical Dirichlet Process简介

    Hierarchical Dirichlet Process简单介绍

Global site tag (gtag.js) - Google Analytics