|
I stick my finger into existence and it smells of nothing. Where am I? What is this called the world? Who is it that lured me here? How did I come into this world? Why was I not consulted? Oh I stick my finger into existence and it smells of nothing.
- Søren Kierkegaard | |
PostgreSQL XML
Table of Contents
As of version 8.3 (not yet in Beta as of this writing), PostgreSQL supports a native XML data type and implements SQL/XML 2003. This data type is capable of storing well formed documents and content fragments. SQL/XML, an alternative to XQuery, is specifically designed for working with XML in relational databases.
Create a document from plain XML text:
example=# SELECT XMLPARSE (DOCUMENT '<?xml version="1.0" encoding="UTF-8"?>
example'# <root>
example'# <parent name="p1">
example'# <child name="c1">Child One</child>
example'# <child name="c2">Child Two</child>
example'# <child name="c3" />
example'# </parent>
example'# <parent name="p2" />
example'# </root>');
xmlparse
--------------------------------------------
<root>
<parent name="p1">
<child name="c1">Child One</child>
<child name="c2">Child Two</child>
<child name="c3" />
</parent>
<parent name="p2" />
</root>
(1 row)
Or typecast the text to XML:
example=# SELECT xml '<root>
example'# <parent name="p1">
example'# <child name="c1">Child One</child>
example'# <child name="c2">Child Two</child>
example'# <child name="c3" />
example'# </parent>
example'# <parent name="p2" />
example'# </root>'::xml;
xml
--------------------------------------------
<root>
<parent name="p1">
<child name="c1">Child One</child>
<child name="c2">Child Two</child>
<child name="c3" />
</parent>
<parent name="p2" />
</root>
(1 row)
Take an XML document and convert it to a genuine character string:
example=# SELECT XMLSERIALIZE(DOCUMENT '<?xml version="1.0" encoding="UTF-8"?>
example'# <root>
example'# <parent name="p1">
example'# <child name="c1">Child One</child>
example'# <child name="c2">Child Two</child>
example'# <child name="c3" />
example'# </parent>
example'# <parent name="p2" />
example'# </root>'::xml AS text);
xmlserialize
--------------------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<root>
<parent name="p1">
<child name="c1">Child One</child>
<child name="c2">Child Two</child>
<child name="c3" />
</parent>
<parent name="p2" />
</root>
(1 row)
A more likely real-world use would be on a table with a column with the xml data type:
example=# SELECT XMLSERIALIZE(DOCUMENT doc_content AS text) from test;
xmlserialize
--------------------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<root>
<parent name="p1">
<child name="c1">Child One</child>
<child name="c2">Child Two</child>
<child name="c3" />
</parent>
<parent name="p2" />
</root>
(1 row)
PostgreSQL's XML functionality extends to more than just basic documents and content. The basics of SQL/XML 2003 are implemented to help make working with XML data much easier.
XMLCOMMENT can be used to create a comment:
example=# SELECT XMLCOMMENT(' This is a comment ');
xmlcomment
------------------------------
<!-- This is a comment -->
(1 row)
Perhaps a more likely real-world example:
example=# SELECT XMLCOMMENT('This comes from the ' || doc_name || ' document')
example-# FROM test;
xmlcomment
-----------------------------------------------
<!--This comes from the test1.xml document-->
(1 row)
XMLCONCAT can take an arbitrary series of XML content and piece them together for a single result:
example=# SELECT XMLCONCAT( XMLCOMMENT('begin chapter one'), '
example'# <chapter number="1" />
example'# ', XMLCOMMENT('begin chapter two'), '
example'# <chapter number="2" />
example'# ', XMLCOMMENT('begin chapter three'), '
example'# <chapter number="3" />');
xmlconcat
----------------------------
<!--begin chapter one-->
<chapter number="1" />
<!--begin chapter two-->
<chapter number="2" />
<!--begin chapter three-->
<chapter number="3" />
(1 row)
Combining XML documents with declarations:
example=# SELECT XMLCONCAT('<?xml version="1.1" encoding="UTF-8"?>
example'# <chapter number="1" />
example'# ', '<?xml version="1.1" encoding="UTF-8"?><chapter number="2" />
example'# ', '<?xml version="1.1" encoding="UTF-8"?><chapter number="3" />');
xmlconcat
------------------------
<?xml version="1.1"?>
<chapter number="1" />
<chapter number="2" />
<chapter number="3" />
(1 row)
Note that conflicting declaration attributes get discarded. The same statement with <?xml version="1.0"?> will get the entire declaration discarded always.
XMLELEMENT is used to construct individual elements. It takes a name, a series of attributes, and then the content of the element. It can use other statements or expressions to help build the pieces of the XML Element:
example=# SELECT XMLELEMENT(name chapter,
example(# XMLATTRIBUTES(
example(# '1' AS number,
example(# CURRENT_DATE as current_date,
example(# (SELECT doc_name FROM test) AS doc_name),
example(# 'The content of chapter one');
xmlelement
---------------------------------------------------------------------------------------------------------
<chapter number="1" current_date="2007-09-20" doc_name="test1.xml">The content of chapter one</chapter>
(1 row)
XMLFOREST is used to create an arbitrary series of XML nodes. The result is not well formed XML, but it can be used for further processing or for inclusion within a larger document.
example=# SELECT XMLFOREST(table_name, column_name)
example-# FROM information_schema.columns
example-# WHERE table_schema = 'public';
xmlforest
---------------------------------------------------------------------
<table_name>test</table_name><column_name>doc_name</column_name>
<table_name>test</table_name><column_name>doc_content</column_name>
(2 rows)
XMLPI is used for creating XML Processing Instructions. These are useful for further document processing (via XSL, for example).
example=# SELECT XMLPI(name php, 'echo "hello world";');
xmlpi
-----------------------------
<?php echo "hello world";?>
(1 row)
A more complex example:
example=# SELECT XMLELEMENT(
example(# name chapter,
example(# XMLATTRIBUTES('1' AS number),
example(# 'Chapter One Content',
example(# XMLPI(name mycustompi, ' doc="' || (SELECT doc_name FROM test) || '"'));
xmlelement
---------------------------------------------------------------------------------
<chapter number="1">Chapter One Content<?mycustompi doc="test1.xml"?></chapter>
(1 row)
|
|