Adding a Style-sheet Declaration to your XML Output

A common requirement for formatting XML output from XQuery expressions, is to be able to add a style-sheet declaration. Style-sheet declarations consist of a standard processing-instruction node that appears at the top-level of the XML. In the following example, we are attempting to construct a PI node, then select a peice of XML that will make up the body of the result:

 declare @x xml
set @x='<myXML/>'

select @x.query('
<?xml-stylesheet type="text/xsl" href="my-style-sheet.xsl" ?>
/.
')

But, when you try and execute this query, you receive the following error:

 Msg 2373, Level 16, State 1, Line 6
XQuery [query()]: '/' is not supported with constructed XML

The problem here is that the query above becomes a single XQuery expression, which equates to building a PI and then querying it out (with the /.). In order to create both the PI and select the existing data from the source instance, we need to use the sequence constructor (,) to break this query up into two seperate expressions - one for generating the PI and the other for serializing out the existing data. Thus, the query above becomes:

 declare @x xml
set @x='<myXML/>'

select @x.query('
<?xml-stylesheet type="text/xsl" href="my-style-sheet.xsl" ?> , 
/.
')

Notice the comma character after the style-sheet PI construction. This is the XQuery sequence constructor syntax and allows us to chain multiple XQuery expressions together to produce a single output. This query will now return the required peice of XML:

 <?xml-stylesheet type="text/xsl" href="my-style-sheet.xsl" ?>
<myXML />

Similarly, if we simply wanted to construct the XML as part of the XQuery expression itself, we would still need to seperate the constructor expressions for each of the XML nodes with a sequence constructor. For example:

 declare @x xml
set @x=''

select @x.query('
<?xml-stylesheet type="text/xsl" href="my-style-sheet.xsl" ?> , 
<MyXML />
')

Without the sequence constructor, this query would also raise an error.

-
Disclaimer:
This posting is provided “AS IS” with no waranties, and confers no rights.
Use of included script samples are subject to the terms specified at https://www.microsoft.com/info/cpyright.htm.