document Function
Provides a way to retrieve other XML resources from within the XSLT style sheet beyond the initial data provided by the input stream.
node-set document(object, node-set?)
Remarks
The effects of the document()
function vary, depending on the type and number of arguments supplied.
- If only one argument is provided and that argument is a string,
document()
treats the string as a URL and retrieves the document as a set of nodes. See Example 1 below for a code illustration. - If only one argument is provided and that argument is a node set, then each node in that node set is treated as a URL and the function returns the union of all of the documents referenced. See Example 2 below for a code illustration.
- If there are two arguments, the first argument can be either a string or a node set while the second argument must be a node set. The second argument, when supplied, serves to indicate the base URL to which the contents of the first argument are relative. See Example 3 below for a code illustration.
- If an empty string is passed to the
document()
function, the result is the source XML of the XSLT document itself, unless the second argument is given (and is not null). In the latter case, the URL of the document is the base URL of the node contained in the second element.
When an XML document is downloaded from within an ASP page using the document()
function with an absolute URL as its argument, the ServerHTTPRequest
property must be set to true
on the DOM object holding the XSLT style sheet before any transformation is initiated, as shown in the following JScript code fragment:
xsltDom.setProperty("ServerHTTPRequest", true);
The reason for this is that MXSML uses URLMON.dll as the default to support file download. However, ASP does not support URLMON. Therefore, you need to set this property to choose WinHTTP.dll as the alternative to downloads.
Example 1
In this example, the XSLT style sheet (document.xsl) performs the following steps:
- Uses the
document()
function to download two XML documents (hrGroup.xml and myGroup.xml) referenced in the source XML document (document.xml). - Extracts the
<group>
elements from the downloaded documents. - Inserts the extracted elements into the resultant XML document.
The effect of the transformation is to resolve the references in document.xml. When a relative path is used to refer the external XML document, the base URL is that of the XSLT style sheet.
When the transformation is initiated from a script in an ASP page (document.asp), the ServerHTTPRequest
property is set to true
. This is not necessary when the transformation is started in JScript (document.js) and executed within the Windows Scripting Host or an HTML page. Here Windows Script Host is used.
Note To test this example, you need to use a script. For more information, see Initiate XSLT in a Script.
XML File (document.xml)
<?xml version='1.0'?> <groups> <groupRef href="http://localhost/hr/hrGroup.xml"/> <groupRef href="myGroup.xml"/> </groups>
Referenced XML File 1 (hrGroup.xml)
<?xml version='1.0'?> <group name="hr"> <leader>mo</leader> <member>bo</member> <member>ko</member> <member>lo</member> </group>
Referenced XML File 2 (myGroup.xml)
<?xml version='1.0'?> <group name="my"> <leader>john</leader> <member>jane</member> <member>jon</member> <member>jan</member> </group>
XSLT File (document.xsl)
<?xml version='1.0'?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <groups> <xsl:apply-templates select="//groupRef"/> </groups> </xsl:template> <xsl:template match="groupRef"> <xsl:copy-of select="document(@href)//group"/> </xsl:template> </xsl:stylesheet>
ASP File (document.asp)
<%@ LANGUAGE = JScript %> <% // Set the source and style sheet locations here. var sourceFile = Server.MapPath("document.xml"); var styleFile = Server.MapPath("document.xsl"); // Load the XML. var source = Server.CreateObject("Msxml2.DOMDocument.5.0"); source.async = false; source.load(sourceFile); // Load the XSLT. var style = Server.CreateObject("Msxml2.DOMDocument.5.0"); style.async = false; style.setProperty("ServerHTTPRequest", true); style.load(styleFile); Response.Write(source.transformNode(style)); %>
JScript File (document.js)
// Set the source and style sheet locations here. var sourceFile = ("document.xml"); var styleFile = ("document.xsl"); // Load the XML. var source = new ActiveXObject("Msxml2.DOMDocument.5.0"); source.async = false; source.load(sourceFile); // Load the XSLT. var style =new ActiveXObject("Msxml2.DOMDocument.5.0"); style.async = false; style.load(styleFile); WScript.Echo(source.transformNode(style));
Try It!
- Copy the code samples above, and paste them into files on your local drive.
- Save the files with the given names and extensions.
- Create a new virtual directory, aliased as hr, under the default Web site on your local machine. If you use a remote machine as the web server, change localhost to the host name of the Web server in the value of the
href
attribute in the document.xml. If you use an existing virtual directory, change hr in the samehref
attribute value to whatever alias that directory has. Move the hrGroup.xml file to the directory that has been made the virtual directory of the Web server. - Open the ASP page from an Internet Explorer browser window with the following URL:
http://localhost/hr/document.asp
- Run the JScript file using the following Windows Scripting Host command:
cscript document.js
Output
The following is the processor output, with indentation added for clarity.
<?xml version="1.0"?> <groups> <group name="hr"> <leader>mo</leader> <member>bo</member> <member>ko</member> <member>lo</member> </group> <group name="my"> <leader>john</leader> <member>jane</member> <member>jon</member> <member>jan</member> </group> </grops>
Example 2
This example illustrates the effects of using a node set as the argument for the document
function.
XML File (document1.xml)
<?xml version='1.0' encoding="UTF-8" ?> <?xml-stylesheet type="text/xsl" href="document1.xsl" ?> <groups> <groupRef>hrGroup1.xml</groupRef> <groupRef>myGroup1.xml</groupRef> </groups>
XSLT Style Sheet (document1.xsl)
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> <xsl:template match="/"> <groups> <xsl:apply-templates select="/groups/groupRef"/> </groups> </xsl:template> <xsl:template match="groups/groupRef"> <xsl:copy-of select="document(.)//group"/> </xsl:template> </xsl:stylesheet>
Try It!
- Download msxsl.exe from msdn.microsoft.com, if you have not already done so.
- From a command prompt, type the following command from the directory where you have saved document1.xml and document1.xsl:
msxsl document1.xml document1.xsl
Output
The output is similar to the output produced in Example 1 above.
Example 3
This example shows the effect of using two arguments when calling the document
function. The second argument, which must be a node set, serves as the base URL for the first argument. When the second argument is absent, the base URL of the first argument is the base URL of the XSLT file.
XSLT Style Sheet (document2.xsl)
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> <xsl:template match="/"> <root> <xsl:comment>One Argument </xsl:comment> <xsl:for-each select="document('b.xml')//a"> <xsl:copy-of select="."/> </xsl:for-each> <xsl:comment>Two Argument </xsl:comment> <xsl:for-each select="document('a.xml', .)//a"> <xsl:copy-of select="."/> </xsl:for-each> </root> </xsl:template> </xsl:stylesheet>
XML File 1 (b.xml)
<doc> <a> one </a> <a> two </a> <a> three </a> </doc>
XML File 2 (subDir/a.xml)
<doc> <a> I </a> <a> II </a> <a> III </a> </doc>
Try It!
- Save document2.xsl and b.xml to a working directory.
- Create a subDir directory under the working directory and save a.xml there.
- From a command prompt type the following command in the working directory:
msxsl.exe subDir\a.xml document2.xsl
Output
<?xml version="1.0" encoding="UTF-8"?> <root> <!-- One Argument --> <a> one </a> <a> two </a> <a> three </a> <!-- Two Arguments --> <a> I </a> <a> II </a> <a> III </a> </root>