4 9.15.1. Producing XML Content
7 9.15.4. Mapping Tables to XML
9 The functions and function-like expressions described in this section
10 operate on values of type xml. See Section 8.13 for information about
11 the xml type. The function-like expressions xmlparse and xmlserialize
12 for converting to and from type xml are documented there, not in this
15 Use of most of these functions requires PostgreSQL to have been built
16 with configure --with-libxml.
18 9.15.1. Producing XML Content #
20 A set of functions and function-like expressions is available for
21 producing XML content from SQL data. As such, they are particularly
22 suitable for formatting query results into XML documents for processing
23 in client applications.
27 xmltext ( text ) → xml
29 The function xmltext returns an XML value with a single text node
30 containing the input argument as its content. Predefined entities like
31 ampersand (&), left and right angle brackets (< >), and quotation marks
35 SELECT xmltext('< foo & bar >');
37 -------------------------
38 < foo & bar >
40 9.15.1.2. xmlcomment #
42 xmlcomment ( text ) → xml
44 The function xmlcomment creates an XML value containing an XML comment
45 with the specified text as content. The text cannot contain “--” or end
46 with a “-”, otherwise the resulting construct would not be a valid XML
47 comment. If the argument is null, the result is null.
50 SELECT xmlcomment('hello');
58 xmlconcat ( xml [, ...] ) → xml
60 The function xmlconcat concatenates a list of individual XML values to
61 create a single value containing an XML content fragment. Null values
62 are omitted; the result is only null if there are no nonnull arguments.
65 SELECT xmlconcat('<abc/>', '<bar>foo</bar>');
68 ----------------------
71 XML declarations, if present, are combined as follows. If all argument
72 values have the same XML version declaration, that version is used in
73 the result, else no version is used. If all argument values have the
74 standalone declaration value “yes”, then that value is used in the
75 result. If all argument values have a standalone declaration value and
76 at least one is “no”, then that is used in the result. Else the result
77 will have no standalone declaration. If the result is determined to
78 require a standalone declaration but no version declaration, a version
79 declaration with version 1.0 will be used because XML requires an XML
80 declaration to contain a version declaration. Encoding declarations are
81 ignored and removed in all cases.
84 SELECT xmlconcat('<?xml version="1.1"?><foo/>', '<?xml version="1.1" standalone=
88 -----------------------------------
89 <?xml version="1.1"?><foo/><bar/>
91 9.15.1.4. xmlelement #
93 xmlelement ( NAME name [, XMLATTRIBUTES ( attvalue [ AS attname ] [, ...] ) ] [,
94 content [, ...]] ) → xml
96 The xmlelement expression produces an XML element with the given name,
97 attributes, and content. The name and attname items shown in the syntax
98 are simple identifiers, not values. The attvalue and content items are
99 expressions, which can yield any PostgreSQL data type. The argument(s)
100 within XMLATTRIBUTES generate attributes of the XML element; the
101 content value(s) are concatenated to form its content.
104 SELECT xmlelement(name foo);
110 SELECT xmlelement(name foo, xmlattributes('xyz' as bar));
116 SELECT xmlelement(name foo, xmlattributes(current_date as bar), 'cont', 'ent');
119 -------------------------------------
120 <foo bar="2007-01-26">content</foo>
122 Element and attribute names that are not valid XML names are escaped by
123 replacing the offending characters by the sequence _xHHHH_, where HHHH
124 is the character's Unicode codepoint in hexadecimal notation. For
126 SELECT xmlelement(name "foo$bar", xmlattributes('xyz' as "a&b"));
129 ----------------------------------
130 <foo_x0024_bar a_x0026_b="xyz"/>
132 An explicit attribute name need not be specified if the attribute value
133 is a column reference, in which case the column's name will be used as
134 the attribute name by default. In other cases, the attribute must be
135 given an explicit name. So this example is valid:
136 CREATE TABLE test (a xml, b xml);
137 SELECT xmlelement(name test, xmlattributes(a, b)) FROM test;
140 SELECT xmlelement(name test, xmlattributes('constant'), a, b) FROM test;
141 SELECT xmlelement(name test, xmlattributes(func(a, b))) FROM test;
143 Element content, if specified, will be formatted according to its data
144 type. If the content is itself of type xml, complex XML documents can
145 be constructed. For example:
146 SELECT xmlelement(name foo, xmlattributes('xyz' as bar),
147 xmlelement(name abc),
149 xmlelement(name xyz));
152 ----------------------------------------------
153 <foo bar="xyz"><abc/><!--test--><xyz/></foo>
155 Content of other types will be formatted into valid XML character data.
156 This means in particular that the characters <, >, and & will be
157 converted to entities. Binary data (data type bytea) will be
158 represented in base64 or hex encoding, depending on the setting of the
159 configuration parameter xmlbinary. The particular behavior for
160 individual data types is expected to evolve in order to align the
161 PostgreSQL mappings with those specified in SQL:2006 and later, as
162 discussed in Section D.3.1.3.
164 9.15.1.5. xmlforest #
166 xmlforest ( content [ AS name ] [, ...] ) → xml
168 The xmlforest expression produces an XML forest (sequence) of elements
169 using the given names and content. As for xmlelement, each name must be
170 a simple identifier, while the content expressions can have any data
174 SELECT xmlforest('abc' AS foo, 123 AS bar);
177 ------------------------------
178 <foo>abc</foo><bar>123</bar>
181 SELECT xmlforest(table_name, column_name)
182 FROM information_schema.columns
183 WHERE table_schema = 'pg_catalog';
186 -----------------------------------------------------------------------
187 <table_name>pg_authid</table_name><column_name>rolname</column_name>
188 <table_name>pg_authid</table_name><column_name>rolsuper</column_name>
191 As seen in the second example, the element name can be omitted if the
192 content value is a column reference, in which case the column name is
193 used by default. Otherwise, a name must be specified.
195 Element names that are not valid XML names are escaped as shown for
196 xmlelement above. Similarly, content data is escaped to make valid XML
197 content, unless it is already of type xml.
199 Note that XML forests are not valid XML documents if they consist of
200 more than one element, so it might be useful to wrap xmlforest
201 expressions in xmlelement.
205 xmlpi ( NAME name [, content ] ) → xml
207 The xmlpi expression creates an XML processing instruction. As for
208 xmlelement, the name must be a simple identifier, while the content
209 expression can have any data type. The content, if present, must not
210 contain the character sequence ?>.
213 SELECT xmlpi(name php, 'echo "hello world";');
216 -----------------------------
217 <?php echo "hello world";?>
221 xmlroot ( xml, VERSION {text|NO VALUE} [, STANDALONE {YES|NO|NO VALUE} ] ) → xml
223 The xmlroot expression alters the properties of the root node of an XML
224 value. If a version is specified, it replaces the value in the root
225 node's version declaration; if a standalone setting is specified, it
226 replaces the value in the root node's standalone declaration.
228 SELECT xmlroot(xmlparse(document '<?xml version="1.1"?><content>abc</content>'),
229 version '1.0', standalone yes);
232 ----------------------------------------
233 <?xml version="1.0" standalone="yes"?>
234 <content>abc</content>
240 The function xmlagg is, unlike the other functions described here, an
241 aggregate function. It concatenates the input values to the aggregate
242 function call, much like xmlconcat does, except that concatenation
243 occurs across rows rather than across expressions in a single row. See
244 Section 9.21 for additional information about aggregate functions.
247 CREATE TABLE test (y int, x xml);
248 INSERT INTO test VALUES (1, '<foo>abc</foo>');
249 INSERT INTO test VALUES (2, '<bar/>');
250 SELECT xmlagg(x) FROM test;
252 ----------------------
255 To determine the order of the concatenation, an ORDER BY clause may be
256 added to the aggregate call as described in Section 4.2.7. For example:
257 SELECT xmlagg(x ORDER BY y DESC) FROM test;
259 ----------------------
262 The following non-standard approach used to be recommended in previous
263 versions, and may still be useful in specific cases:
264 SELECT xmlagg(x) FROM (SELECT * FROM test ORDER BY y DESC) AS tab;
266 ----------------------
269 9.15.2. XML Predicates #
271 The expressions described in this section check properties of xml
274 9.15.2.1. IS DOCUMENT #
276 xml IS DOCUMENT → boolean
278 The expression IS DOCUMENT returns true if the argument XML value is a
279 proper XML document, false if it is not (that is, it is a content
280 fragment), or null if the argument is null. See Section 8.13 about the
281 difference between documents and content fragments.
283 9.15.2.2. IS NOT DOCUMENT #
285 xml IS NOT DOCUMENT → boolean
287 The expression IS NOT DOCUMENT returns false if the argument XML value
288 is a proper XML document, true if it is not (that is, it is a content
289 fragment), or null if the argument is null.
291 9.15.2.3. XMLEXISTS #
293 XMLEXISTS ( text PASSING [BY {REF|VALUE}] xml [BY {REF|VALUE}] ) → boolean
295 The function xmlexists evaluates an XPath 1.0 expression (the first
296 argument), with the passed XML value as its context item. The function
297 returns false if the result of that evaluation yields an empty
298 node-set, true if it yields any other value. The function returns null
299 if any argument is null. A nonnull value passed as the context item
300 must be an XML document, not a content fragment or any non-XML value.
303 SELECT xmlexists('//town[text() = ''Toronto'']' PASSING BY VALUE '<towns><town>T
304 oronto</town><town>Ottawa</town></towns>');
311 The BY REF and BY VALUE clauses are accepted in PostgreSQL, but are
312 ignored, as discussed in Section D.3.2.
314 In the SQL standard, the xmlexists function evaluates an expression in
315 the XML Query language, but PostgreSQL allows only an XPath 1.0
316 expression, as discussed in Section D.3.1.
318 9.15.2.4. xml_is_well_formed #
320 xml_is_well_formed ( text ) → boolean
321 xml_is_well_formed_document ( text ) → boolean
322 xml_is_well_formed_content ( text ) → boolean
324 These functions check whether a text string represents well-formed XML,
325 returning a Boolean result. xml_is_well_formed_document checks for a
326 well-formed document, while xml_is_well_formed_content checks for
327 well-formed content. xml_is_well_formed does the former if the
328 xmloption configuration parameter is set to DOCUMENT, or the latter if
329 it is set to CONTENT. This means that xml_is_well_formed is useful for
330 seeing whether a simple cast to type xml will succeed, whereas the
331 other two functions are useful for seeing whether the corresponding
332 variants of XMLPARSE will succeed.
335 SET xmloption TO DOCUMENT;
336 SELECT xml_is_well_formed('<>');
342 SELECT xml_is_well_formed('<abc/>');
348 SET xmloption TO CONTENT;
349 SELECT xml_is_well_formed('abc');
355 SELECT xml_is_well_formed_document('<pg:foo xmlns:pg="http://postgresql.org/stuf
357 xml_is_well_formed_document
358 -----------------------------
362 SELECT xml_is_well_formed_document('<pg:foo xmlns:pg="http://postgresql.org/stuf
364 xml_is_well_formed_document
365 -----------------------------
369 The last example shows that the checks include whether namespaces are
372 9.15.3. Processing XML #
374 To process values of data type xml, PostgreSQL offers the functions
375 xpath and xpath_exists, which evaluate XPath 1.0 expressions, and the
376 XMLTABLE table function.
380 xpath ( xpath text, xml xml [, nsarray text[] ] ) → xml[]
382 The function xpath evaluates the XPath 1.0 expression xpath (given as
383 text) against the XML value xml. It returns an array of XML values
384 corresponding to the node-set produced by the XPath expression. If the
385 XPath expression returns a scalar value rather than a node-set, a
386 single-element array is returned.
388 The second argument must be a well formed XML document. In particular,
389 it must have a single root node element.
391 The optional third argument of the function is an array of namespace
392 mappings. This array should be a two-dimensional text array with the
393 length of the second axis being equal to 2 (i.e., it should be an array
394 of arrays, each of which consists of exactly 2 elements). The first
395 element of each array entry is the namespace name (alias), the second
396 the namespace URI. It is not required that aliases provided in this
397 array be the same as those being used in the XML document itself (in
398 other words, both in the XML document and in the xpath function
399 context, aliases are local).
402 SELECT xpath('/my:a/text()', '<my:a xmlns:my="http://example.com">test</my:a>',
403 ARRAY[ARRAY['my', 'http://example.com']]);
410 To deal with default (anonymous) namespaces, do something like this:
411 SELECT xpath('//mydefns:b/text()', '<a xmlns="http://example.com"><b>test</b></a
413 ARRAY[ARRAY['mydefns', 'http://example.com']]);
420 9.15.3.2. xpath_exists #
422 xpath_exists ( xpath text, xml xml [, nsarray text[] ] ) → boolean
424 The function xpath_exists is a specialized form of the xpath function.
425 Instead of returning the individual XML values that satisfy the XPath
426 1.0 expression, this function returns a Boolean indicating whether the
427 query was satisfied or not (specifically, whether it produced any value
428 other than an empty node-set). This function is equivalent to the
429 XMLEXISTS predicate, except that it also offers support for a namespace
433 SELECT xpath_exists('/my:a/text()', '<my:a xmlns:my="http://example.com">test</m
435 ARRAY[ARRAY['my', 'http://example.com']]);
445 [ XMLNAMESPACES ( namespace_uri AS namespace_name [, ...] ), ]
446 row_expression PASSING [BY {REF|VALUE}] document_expression [BY {REF|VALUE}]
447 COLUMNS name { type [PATH column_expression] [DEFAULT default_expression] [N
453 The xmltable expression produces a table based on an XML value, an
454 XPath filter to extract rows, and a set of column definitions. Although
455 it syntactically resembles a function, it can only appear as a table in
456 a query's FROM clause.
458 The optional XMLNAMESPACES clause gives a comma-separated list of
459 namespace definitions, where each namespace_uri is a text expression
460 and each namespace_name is a simple identifier. It specifies the XML
461 namespaces used in the document and their aliases. A default namespace
462 specification is not currently supported.
464 The required row_expression argument is an XPath 1.0 expression (given
465 as text) that is evaluated, passing the XML value document_expression
466 as its context item, to obtain a set of XML nodes. These nodes are what
467 xmltable transforms into output rows. No rows will be produced if the
468 document_expression is null, nor if the row_expression produces an
469 empty node-set or any value other than a node-set.
471 document_expression provides the context item for the row_expression.
472 It must be a well-formed XML document; fragments/forests are not
473 accepted. The BY REF and BY VALUE clauses are accepted but ignored, as
474 discussed in Section D.3.2.
476 In the SQL standard, the xmltable function evaluates expressions in the
477 XML Query language, but PostgreSQL allows only XPath 1.0 expressions,
478 as discussed in Section D.3.1.
480 The required COLUMNS clause specifies the column(s) that will be
481 produced in the output table. See the syntax summary above for the
482 format. A name is required for each column, as is a data type (unless
483 FOR ORDINALITY is specified, in which case type integer is implicit).
484 The path, default and nullability clauses are optional.
486 A column marked FOR ORDINALITY will be populated with row numbers,
487 starting with 1, in the order of nodes retrieved from the
488 row_expression's result node-set. At most one column may be marked FOR
493 XPath 1.0 does not specify an order for nodes in a node-set, so code
494 that relies on a particular order of the results will be
495 implementation-dependent. Details can be found in Section D.3.1.2.
497 The column_expression for a column is an XPath 1.0 expression that is
498 evaluated for each row, with the current node from the row_expression
499 result as its context item, to find the value of the column. If no
500 column_expression is given, then the column name is used as an implicit
503 If a column's XPath expression returns a non-XML value (which is
504 limited to string, boolean, or double in XPath 1.0) and the column has
505 a PostgreSQL type other than xml, the column will be set as if by
506 assigning the value's string representation to the PostgreSQL type. (If
507 the value is a boolean, its string representation is taken to be 1 or 0
508 if the output column's type category is numeric, otherwise true or
511 If a column's XPath expression returns a non-empty set of XML nodes and
512 the column's PostgreSQL type is xml, the column will be assigned the
513 expression result exactly, if it is of document or content form. ^[8]
515 A non-XML result assigned to an xml output column produces content, a
516 single text node with the string value of the result. An XML result
517 assigned to a column of any other type may not have more than one node,
518 or an error is raised. If there is exactly one node, the column will be
519 set as if by assigning the node's string value (as defined for the
520 XPath 1.0 string function) to the PostgreSQL type.
522 The string value of an XML element is the concatenation, in document
523 order, of all text nodes contained in that element and its descendants.
524 The string value of an element with no descendant text nodes is an
525 empty string (not NULL). Any xsi:nil attributes are ignored. Note that
526 the whitespace-only text() node between two non-text elements is
527 preserved, and that leading whitespace on a text() node is not
528 flattened. The XPath 1.0 string function may be consulted for the rules
529 defining the string value of other XML node types and non-XML values.
531 The conversion rules presented here are not exactly those of the SQL
532 standard, as discussed in Section D.3.1.3.
534 If the path expression returns an empty node-set (typically, when it
535 does not match) for a given row, the column will be set to NULL, unless
536 a default_expression is specified; then the value resulting from
537 evaluating that expression is used.
539 A default_expression, rather than being evaluated immediately when
540 xmltable is called, is evaluated each time a default is needed for the
541 column. If the expression qualifies as stable or immutable, the repeat
542 evaluation may be skipped. This means that you can usefully use
543 volatile functions like nextval in default_expression.
545 Columns may be marked NOT NULL. If the column_expression for a NOT NULL
546 column does not match anything and there is no DEFAULT or the
547 default_expression also evaluates to null, an error is reported.
550 CREATE TABLE xmldata AS SELECT
554 <COUNTRY_ID>AU</COUNTRY_ID>
555 <COUNTRY_NAME>Australia</COUNTRY_NAME>
558 <COUNTRY_ID>JP</COUNTRY_ID>
559 <COUNTRY_NAME>Japan</COUNTRY_NAME>
560 <PREMIER_NAME>Shinzo Abe</PREMIER_NAME>
561 <SIZE unit="sq_mi">145935</SIZE>
564 <COUNTRY_ID>SG</COUNTRY_ID>
565 <COUNTRY_NAME>Singapore</COUNTRY_NAME>
566 <SIZE unit="sq_km">697</SIZE>
573 XMLTABLE('//ROWS/ROW'
575 COLUMNS id int PATH '@id',
576 ordinality FOR ORDINALITY,
578 country_id text PATH 'COUNTRY_ID',
579 size_sq_km float PATH 'SIZE[@unit = "sq_km"]',
581 'concat(SIZE[@unit!="sq_km"], " ", SIZE[@unit!="sq_
583 premier_name text PATH 'PREMIER_NAME' DEFAULT 'not speci
586 id | ordinality | COUNTRY_NAME | country_id | size_sq_km | size_other | premi
588 ----+------------+--------------+------------+------------+--------------+------
590 1 | 1 | Australia | AU | | | not s
592 5 | 2 | Japan | JP | | 145935 sq_mi | Shinz
594 6 | 3 | Singapore | SG | 697 | | not s
597 The following example shows concatenation of multiple text() nodes,
598 usage of the column name as XPath filter, and the treatment of
599 whitespace, XML comments and processing instructions:
600 CREATE TABLE xmlelements AS SELECT
603 <element> Hello<!-- xyxxz -->2a2<?aaaaa?> <!--x--> bbb<x>xxx</x>CC </eleme
609 FROM xmlelements, XMLTABLE('/root' PASSING data COLUMNS element text);
611 -------------------------
614 The following example illustrates how the XMLNAMESPACES clause can be
615 used to specify a list of namespaces used in the XML document as well
616 as in the XPath expressions:
617 WITH xmldata(data) AS (VALUES ('
618 <example xmlns="http://example.com/myns" xmlns:B="http://example.com/b">
619 <item foo="1" B:bar="2"/>
620 <item foo="3" B:bar="4"/>
621 <item foo="4" B:bar="5"/>
625 FROM XMLTABLE(XMLNAMESPACES('http://example.com/myns' AS x,
626 'http://example.com/b' AS "B"),
628 PASSING (SELECT data FROM xmldata)
629 COLUMNS foo int PATH '@foo',
630 bar int PATH '@B:bar');
638 9.15.4. Mapping Tables to XML #
640 The following functions map the contents of relational tables to XML
641 values. They can be thought of as XML export functionality:
642 table_to_xml ( table regclass, nulls boolean,
643 tableforest boolean, targetns text ) → xml
644 query_to_xml ( query text, nulls boolean,
645 tableforest boolean, targetns text ) → xml
646 cursor_to_xml ( cursor refcursor, count integer, nulls boolean,
647 tableforest boolean, targetns text ) → xml
649 table_to_xml maps the content of the named table, passed as parameter
650 table. The regclass type accepts strings identifying tables using the
651 usual notation, including optional schema qualification and double
652 quotes (see Section 8.19 for details). query_to_xml executes the query
653 whose text is passed as parameter query and maps the result set.
654 cursor_to_xml fetches the indicated number of rows from the cursor
655 specified by the parameter cursor. This variant is recommended if large
656 tables have to be mapped, because the result value is built up in
657 memory by each function.
659 If tableforest is false, then the resulting XML document looks like
663 <columnname1>data</columnname1>
664 <columnname2>data</columnname2>
674 If tableforest is true, the result is an XML content fragment that
677 <columnname1>data</columnname1>
678 <columnname2>data</columnname2>
687 If no table name is available, that is, when mapping a query or a
688 cursor, the string table is used in the first format, row in the second
691 The choice between these formats is up to the user. The first format is
692 a proper XML document, which will be important in many applications.
693 The second format tends to be more useful in the cursor_to_xml function
694 if the result values are to be reassembled into one document later on.
695 The functions for producing XML content discussed above, in particular
696 xmlelement, can be used to alter the results to taste.
698 The data values are mapped in the same way as described for the
699 function xmlelement above.
701 The parameter nulls determines whether null values should be included
702 in the output. If true, null values in columns are represented as:
703 <columnname xsi:nil="true"/>
705 where xsi is the XML namespace prefix for XML Schema Instance. An
706 appropriate namespace declaration will be added to the result value. If
707 false, columns containing null values are simply omitted from the
710 The parameter targetns specifies the desired XML namespace of the
711 result. If no particular namespace is wanted, an empty string should be
714 The following functions return XML Schema documents describing the
715 mappings performed by the corresponding functions above:
716 table_to_xmlschema ( table regclass, nulls boolean,
717 tableforest boolean, targetns text ) → xml
718 query_to_xmlschema ( query text, nulls boolean,
719 tableforest boolean, targetns text ) → xml
720 cursor_to_xmlschema ( cursor refcursor, nulls boolean,
721 tableforest boolean, targetns text ) → xml
723 It is essential that the same parameters are passed in order to obtain
724 matching XML data mappings and XML Schema documents.
726 The following functions produce XML data mappings and the corresponding
727 XML Schema in one document (or forest), linked together. They can be
728 useful where self-contained and self-describing results are wanted:
729 table_to_xml_and_xmlschema ( table regclass, nulls boolean,
730 tableforest boolean, targetns text ) → xml
731 query_to_xml_and_xmlschema ( query text, nulls boolean,
732 tableforest boolean, targetns text ) → xml
734 In addition, the following functions are available to produce analogous
735 mappings of entire schemas or the entire current database:
736 schema_to_xml ( schema name, nulls boolean,
737 tableforest boolean, targetns text ) → xml
738 schema_to_xmlschema ( schema name, nulls boolean,
739 tableforest boolean, targetns text ) → xml
740 schema_to_xml_and_xmlschema ( schema name, nulls boolean,
741 tableforest boolean, targetns text ) → xml
743 database_to_xml ( nulls boolean,
744 tableforest boolean, targetns text ) → xml
745 database_to_xmlschema ( nulls boolean,
746 tableforest boolean, targetns text ) → xml
747 database_to_xml_and_xmlschema ( nulls boolean,
748 tableforest boolean, targetns text ) → xml
750 These functions ignore tables that are not readable by the current
751 user. The database-wide functions additionally ignore schemas that the
752 current user does not have USAGE (lookup) privilege for.
754 Note that these potentially produce a lot of data, which needs to be
755 built up in memory. When requesting content mappings of large schemas
756 or databases, it might be worthwhile to consider mapping the tables
757 separately instead, possibly even through a cursor.
759 The result of a schema content mapping looks like this:
770 where the format of a table mapping depends on the tableforest
771 parameter as explained above.
773 The result of a database content mapping looks like this:
788 where the schema mapping is as above.
790 As an example of using the output produced by these functions,
791 Example 9.1 shows an XSLT stylesheet that converts the output of
792 table_to_xml_and_xmlschema to an HTML document containing a tabular
793 rendition of the table data. In a similar manner, the results from
794 these functions can be converted into other XML-based formats.
796 Example 9.1. XSLT Stylesheet for Converting SQL/XML Output to HTML
797 <?xml version="1.0"?>
798 <xsl:stylesheet version="1.0"
799 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
800 xmlns:xsd="http://www.w3.org/2001/XMLSchema"
801 xmlns="http://www.w3.org/1999/xhtml"
804 <xsl:output method="xml"
805 doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
806 doctype-public="-//W3C/DTD XHTML 1.0 Strict//EN"
809 <xsl:template match="/*">
810 <xsl:variable name="schema" select="//xsd:schema"/>
811 <xsl:variable name="tabletypename"
812 select="$schema/xsd:element[@name=name(current())]/@type"/>
813 <xsl:variable name="rowtypename"
814 select="$schema/xsd:complexType[@name=$tabletypename]/xsd:sequ
815 ence/xsd:element[@name='row']/@type"/>
819 <title><xsl:value-of select="name(current())"/></title>
824 <xsl:for-each select="$schema/xsd:complexType[@name=$rowtypename]/xs
825 d:sequence/xsd:element/@name">
826 <th><xsl:value-of select="."/></th>
830 <xsl:for-each select="row">
832 <xsl:for-each select="*">
833 <td><xsl:value-of select="."/></td>
844 ^[8] A result containing more than one element node at the top level,
845 or non-whitespace text outside of an element, is an example of content
846 form. An XPath result can be of neither form, for example if it returns
847 an attribute node selected from the element that contains it. Such a
848 result will be put into content form with each such disallowed node
849 replaced by its string value, as defined for the XPath 1.0 string