On Mon, 2006-08-21 at 23:38 -0400, Bruce Momjian wrote:
[snip]
>
> FYI, I have not seen a patch for this yet.
>
Thanks for prodding me to submit it. Attached is the documentation
patch, based on Phillipe's example.
Regards
John
Index: contrib/xml2/README.xml2
===
RCS file: /projects/cvsroot/pgsql/contrib/xml2/README.xml2,v
retrieving revision 1.3
diff -c -r1.3 README.xml2
*** contrib/xml2/README.xml2 22 Jan 2005 22:14:14 - 1.3
--- contrib/xml2/README.xml2 22 Aug 2006 20:19:39 -
***
*** 83,89
key - the name of the "key" field - this is just a field to be used as
the first column of the output table i.e. it identifies the record from
! which each output row came.
document - the name of the field containing the XML document
--- 83,89
key - the name of the "key" field - this is just a field to be used as
the first column of the output table i.e. it identifies the record from
! which each output row came (see note below about multiple values).
document - the name of the field containing the XML document
***
*** 150,155
--- 150,229
as a more complicated example. Of course, you could wrap all
of this in a view for convenience.
+ Multivalued results
+
+ The xpath_table function assumes that the results of each XPath query
+ might be multi-valued, so the number of rows returned by the function
+ may not be the same as the number of input documents. The first row
+ returned contains the first result from each query, the second row the
+ second result from each query. If one of the queries has fewer values
+ than the others, NULLs will be returned instead.
+
+ In some cases, a user will know that a given XPath query will return
+ only a single result (perhaps a unique document identifier) - if used
+ alongside an XPath query returning multiple results, the single-valued
+ result will appear only on the first row of the result. The solution
+ to this is to use the key field as part of a join against a simpler
+ XPath query. As an example:
+
+
+ CREATE TABLE test
+ (
+ id int4 NOT NULL,
+ xml text,
+ CONSTRAINT pk PRIMARY KEY (id)
+ )
+ WITHOUT OIDS;
+
+ INSERT INTO test VALUES (1, '
+ 123
+ 112233
+ ');
+
+ INSERT INTO test VALUES (2, '
+ 111222333
+ 111222333
+ ');
+
+
+ The query:
+
+ SELECT * FROM xpath_table('id','xml','test',
+ '/doc/@num|/doc/line/@num|/doc/line/a|/doc/line/b|/doc/line/c','1=1')
+ AS t(id int4, doc_num varchar(10), line_num varchar(10), val1 int4,
+ val2 int4, val3 int4)
+ WHERE id = 1 ORDER BY doc_num, line_num
+
+
+ Gives the result:
+
+ id | doc_num | line_num | val1 | val2 | val3
+ +-+--+--+--+--
+ 1 | C1 | L1 |1 |2 |3
+ 1 | | L2 | 11 | 22 | 33
+
+ To get doc_num on every line, the solution is to use two invocations
+ of xpath_table and join the results:
+
+ SELECT t.*,i.doc_num FROM
+ xpath_table('id','xml','test',
+'/doc/line/@num|/doc/line/a|/doc/line/b|/doc/line/c','1=1')
+ AS t(id int4, line_num varchar(10), val1 int4, val2 int4, val3 int4),
+ xpath_table('id','xml','test','/doc/@num','1=1')
+ AS i(id int4, doc_num varchar(10))
+ WHERE i.id=t.id AND i.id=1
+ ORDER BY doc_num, line_num;
+
+ which gives the desired result:
+
+ id | line_num | val1 | val2 | val3 | doc_num
+ +--+--+--+--+-
+ 1 | L1 |1 |2 |3 | C1
+ 1 | L2 | 11 | 22 | 33 | C1
+ (2 rows)
+
+
+
XSLT functions
--
---(end of broadcast)---
TIP 4: Have you searched our list archives?
http://archives.postgresql.org