{"id":73286,"date":"2012-09-05T08:00:16","date_gmt":"2012-09-05T08:00:16","guid":{"rendered":"https:\/\/www.red-gate.com\/simple-talk\/uncategorized\/generating-xml-from-sql-and-pl-sql-part-1\/"},"modified":"2021-07-14T13:07:51","modified_gmt":"2021-07-14T13:07:51","slug":"generating-xml-from-sql-and-pl-sql-part-1","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/databases\/oracle-databases\/generating-xml-from-sql-and-pl-sql-part-1\/","title":{"rendered":"Generating XML from SQL and PL\/SQL &#8211; Part 1: Introduction"},"content":{"rendered":"<p>From time to time you&#8217;ll have to represent your data stored in a database in an XML format, eg. to exchange it between systems, to send it to external parties, etc. In this introduction, I&#8217;ll show you step by step using small examples how you can easily generate XML from tables.<\/p>\n<h2>SQL<\/h2>\n<p>There are some SQL functions available to generate XML. The first function is XMLElement, it creates an element for the data specified, usually coming from a table column:<\/p>\n<pre>SELECT XMLElement( \"DEPARTMENT\"\r\n                 , department_name\r\n                 )\r\n  FROM departments\r\n WHERE department_id IN (10, 20);<\/pre>\n<p>Resulting in these two rows(from two records):<\/p>\n<pre>&lt;DEPARTMENT&gt;Administration&lt;\/DEPARTMENT&gt;\r\n&lt;DEPARTMENT&gt;Marketing&lt;\/DEPARTMENT&gt;<\/pre>\n<p>That&#8217;s the easy part, generating data surrounded with XML tags. But of course you need to add attributes to these elements. This is still easy to do with the XMLAttributes function:<\/p>\n<pre>SELECT XMLElement(\"DEPARTMENT\"\r\n                 , XMLAttributes( department_id as \"ID\"\r\n                                )\r\n                 , department_name\r\n                 )\r\nFROM departments\r\nWHERE department_id IN (10, 20);<\/pre>\n<pre>&lt;DEPARTMENT ID=\"10\"&gt;Administration&lt;\/DEPARTMENT&gt;\r\n&lt;DEPARTMENT ID=\"20\"&gt;Marketing&lt;\/DEPARTMENT&gt;<\/pre>\n<p>OK&#8230;We now can create an XML Element with attributes, but we have more data than one element. So we add another element:<\/p>\n<pre>SELECT XMLElement(\"DEPARTMENT_ID\"\r\n                 , department_id\r\n                 )\r\n     , XMLElement(\"DEPARTMENT\"\r\n                 , department_name\r\n                 )\r\n  FROM departments\r\n WHERE department_id IN (10, 20);<\/pre>\n<p>Result:<\/p>\n<pre>&lt;DEPARTMENT_ID&gt;10&lt;\/DEPARTMENT_ID&gt;     &lt;DEPARTMENT&gt;Administration&lt;\/DEPARTMENT&gt;\r\n&lt;DEPARTMENT_ID&gt;20&lt;\/DEPARTMENT_ID&gt;     &lt;DEPARTMENT&gt;Marketing&lt;\/DEPARTMENT&gt;<\/pre>\n<p>Oops&#8230;two columns, not really the way I wanted it, I want all XML in 1 column. We can use XMLForest for this. \u00a0It generates a forest of XML Elements, i.e. multiple XML Elements:<\/p>\n<pre>SELECT XMLForest(department_id as \"ID\"\r\n                , department_name as \"NAME\"\r\n                )\r\n  FROM departments\r\n WHERE department_id IN (10, 20);<\/pre>\n<pre>&lt;ID&gt;10&lt;\/ID&gt;&lt;NAME&gt;Administration&lt;\/NAME&gt;\r\n&lt;ID&gt;20&lt;\/ID&gt;&lt;NAME&gt;Marketing&lt;\/NAME&gt;<\/pre>\n<p>That&#8217;s more like it, one column for each record. And by combining XML Element and XML Forest we can get this:<\/p>\n<pre>SELECT XMLElement(\"DEPARTMENT\"\r\n                 , XMLForest(department_id as \"ID\"\r\n                            , department_name as \"NAME\"\r\n                            )\r\n                 )\r\n  FROM departments\r\n WHERE department_id IN (10, 20);<\/pre>\n<pre>&lt;DEPARTMENT&gt;&lt;ID&gt;10&lt;\/ID&gt;&lt;NAME&gt;Administration&lt;\/NAME&gt;&lt;\/DEPARTMENT&gt;\r\n&lt;DEPARTMENT&gt;&lt;ID&gt;20&lt;\/ID&gt;&lt;NAME&gt;Marketing&lt;\/NAME&gt;&lt;\/DEPARTMENT&gt;<\/pre>\n<p>An XML Element containing an XML Forest, i.e. one element containing multiple elements.<\/p>\n<p>Up to now, we got multiple rows back from the query. Using XMLAgg we can retrieve one row with all records from the query:<\/p>\n<pre>SELECT XMLAgg(XMLElement(\"DEPARTMENT\"\r\n                        , XMLAttributes( department_id as \"ID\"\r\n                                       )\r\n                        , department_name\r\n                        )\r\n             )\r\n  FROM departments\r\n WHERE department_id IN (10, 20);<\/pre>\n<pre>&lt;DEPARTMENT ID=\"10\"&gt;Administration&lt;\/DEPARTMENT&gt;&lt;DEPARTMENT ID=\"20\"&gt;Marketing&lt;\/DEPARTMENT&gt;<\/pre>\n<p>These are some SQL functions to generate XML and when combining these functions, one can create some nice and more complex XML Documents:<\/p>\n<pre>SELECT XMLElement(\"DEPARTMENT\"\r\n                 , XMLAttributes( department_id as \"ID\"\r\n                                , department_name as \"NAME\"\r\n                                )\r\n                 , XMLElement(\"EMPLOYEES\"\r\n                             , (SELECT XMLAgg( XMLElement(\"EMPLOYEE\"\r\n                                                         , XMLForest(employee_id as \"ID\"\r\n                                                                    ,first_name||' '||last_name as \"NAME\"\r\n                                                                    )\r\n                                                         )\r\n                                             )\r\n                                 FROM employees emp\r\n                                WHERE emp.department_id = dept.department_id\r\n                                )\r\n                              )\r\n                )\r\n  FROM departments dept\r\n WHERE department_id IN (10, 20);<\/pre>\n<p>This query generates two rows, one row for each department:<\/p>\n<ul>\n<li>The &#8220;Department&#8221; element has two attributes (ID and name) and contains an &#8220;Employees&#8221; element<\/li>\n<li>The &#8220;Employees&#8221; element consists of multiple rows (all employees for that department)<\/li>\n<li>Every row of the &#8220;Employees&#8221; element has an &#8220;Employee&#8221; element (single employee record)<\/li>\n<li>Each &#8220;Employee&#8221; element has multiple elements: &#8220;ID&#8221; and &#8220;Name&#8221;<\/li>\n<\/ul>\n<p>It looks like this:<\/p>\n<pre>&lt;DEPARTMENT ID=\"10\" NAME=\"Administration\"&gt;&lt;EMPLOYEES&gt;&lt;EMPLOYEE&gt;&lt;ID&gt;200&lt;\/ID&gt;&lt;NAME&gt;Jennifer Whalen&lt;\/NAME&gt;&lt;\/EMPLOYEE&gt;&lt;\/EMPLOYEES&gt;&lt;\/DEPARTMENT&gt;\r\n&lt;DEPARTMENT ID=\"20\" NAME=\"Marketing\"&gt;&lt;EMPLOYEES&gt;&lt;EMPLOYEE&gt;&lt;ID&gt;201&lt;\/ID&gt;&lt;NAME&gt;Michael Hartstein&lt;\/NAME&gt;&lt;\/EMPLOYEE&gt;&lt;EMPLOYEE&gt;&lt;ID&gt;202&lt;\/ID&gt;&lt;NAME&gt;Pat Fay&lt;\/NAME&gt;&lt;\/EMPLOYEE&gt;&lt;\/EMPLOYEES&gt;&lt;\/DEPARTMENT&gt;<\/pre>\n<p>We can format this to make it clearer:<\/p>\n<pre>&lt;DEPARTMENT ID=\"10\" NAME=\"Administration\"&gt;\r\n  &lt;EMPLOYEES&gt;\r\n    &lt;EMPLOYEE&gt;\r\n      &lt;ID&gt;200&lt;\/ID&gt;\r\n      &lt;NAME&gt;Jennifer Whalen&lt;\/NAME&gt;\r\n    &lt;\/EMPLOYEE&gt;\r\n  &lt;\/EMPLOYEES&gt;\r\n&lt;\/DEPARTMENT&gt;\r\n&lt;DEPARTMENT ID=\"20\" NAME=\"Marketing\"&gt;\r\n  &lt;EMPLOYEES&gt;\r\n    &lt;EMPLOYEE&gt;\r\n      &lt;ID&gt;201&lt;\/ID&gt;\r\n      &lt;NAME&gt;Michael Hartstein&lt;\/NAME&gt;\r\n    &lt;\/EMPLOYEE&gt;\r\n    &lt;EMPLOYEE&gt;\r\n      &lt;ID&gt;202&lt;\/ID&gt;\r\n      &lt;NAME&gt;Pat Fay&lt;\/NAME&gt;\r\n    &lt;\/EMPLOYEE&gt;\r\n  &lt;\/EMPLOYEES&gt;\r\n&lt;\/DEPARTMENT&gt;<\/pre>\n<p>I hope this will be a good start to create XML documents from the data in your tables. In part two I will show you how to create XML from PL\/SQL.<\/p>\n<p>Oracle documentation on <a href=\"http:\/\/docs.oracle.com\/cd\/E11882_01\/appdev.112\/e23094\/xdb13gen.htm#i1029583\" target=\"_blank\">Generating XML using SQL Functions<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>From time to time you&#8217;ll have to represent your data stored in a database in an XML format, eg. to exchange it between systems, to send it to external parties, etc. In this introduction, I&#8217;ll show you step by step using small examples how you can easily generate XML from tables. SQL There are some SQL functions available to generat&hellip;<\/p>\n","protected":false},"author":316191,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[143533],"tags":[],"coauthors":[],"class_list":["post-73286","post","type-post","status-publish","format-standard","hentry","category-oracle-databases"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/73286","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/users\/316191"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=73286"}],"version-history":[{"count":1,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/73286\/revisions"}],"predecessor-version":[{"id":91746,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/73286\/revisions\/91746"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=73286"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=73286"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=73286"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=73286"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}