XSLT - Processing Multiple XML Documents with the document() Function in XSLT
In many real-world applications, information is not stored in a single XML file. Instead, organizations often maintain separate XML documents for different types of data. For example, one XML file may contain employee information, another may store department details, and a third may hold salary records. When generating reports or transforming data, it is often necessary to combine information from multiple XML files into a single output. XSLT provides the document() function to solve this problem by allowing a stylesheet to access and process external XML documents during transformation.
What is the document() Function?
The document() function is an XSLT function that loads one or more external XML documents into the transformation process. It enables the stylesheet to retrieve additional XML data beyond the primary input document.
Syntax:
document(uri)
or
document(uri, node)
-
urispecifies the location of the external XML document. -
nodeis an optional parameter that determines the base URI for resolving relative paths.
The function returns the root node of the specified XML document, allowing XPath expressions to navigate its contents just like the main input document.
Why Use the document() Function?
There are several situations where the document() function becomes extremely useful:
-
Combining information stored across multiple XML files.
-
Creating reports using data from different sources.
-
Maintaining reusable lookup tables.
-
Separating frequently changing data from static data.
-
Improving maintainability by keeping XML files modular.
Instead of storing all information in one massive XML document, developers can organize related data into smaller files and combine them only when needed.
Example Scenario
Suppose a company stores employee information in one XML file and department information in another.
employees.xml
<employees>
<employee>
<id>101</id>
<name>John</name>
<deptid>D1</deptid>
</employee>
<employee>
<id>102</id>
<name>Alice</name>
<deptid>D2</deptid>
</employee>
</employees>
departments.xml
<departments>
<department>
<deptid>D1</deptid>
<departmentname>Human Resources</departmentname>
</department>
<department>
<deptid>D2</deptid>
<departmentname>Finance</departmentname>
</department>
</departments>
The goal is to display each employee along with the corresponding department name.
Using the document() Function
<xsl:variable name="deptDoc"
select="document('departments.xml')"/>
This statement loads the external XML document into a variable named deptDoc.
Now the stylesheet can access department information.
<xsl:for-each select="employees/employee">
<p>
<xsl:value-of select="name"/>
-
<xsl:value-of
select="$deptDoc/departments/department
[deptid=current()/deptid]
/departmentname"/>
</p>
</xsl:for-each>
The transformation searches the external document for the matching department ID and displays the corresponding department name.
Output
John - Human Resources
Alice - Finance
This demonstrates how two independent XML documents can be combined into a single output.
Using Multiple External XML Files
The document() function can load more than one XML file.
Example:
<xsl:variable name="salary"
select="document('salary.xml')"/>
<xsl:variable name="projects"
select="document('projects.xml')"/>
Now the stylesheet has access to:
-
Employee data
-
Salary information
-
Project assignments
All three XML documents can be merged into one report during transformation.
Accessing Dynamic XML Files
Sometimes the filename itself comes from the XML document.
Example XML:
<reports>
<file>sales.xml</file>
<file>marketing.xml</file>
</reports>
XSLT:
<xsl:for-each select="reports/file">
<xsl:variable name="doc"
select="document(.)"/>
</xsl:for-each>
Here, the current XML element contains the filename, and the stylesheet dynamically loads each file during processing.
Using Lookup Tables
A common application of the document() function is creating lookup tables.
Suppose products.xml contains only category IDs.
<product>
<name>Laptop</name>
<category>C1</category>
</product>
categories.xml
<categories>
<category>
<id>C1</id>
<name>Electronics</name>
</category>
</categories>
Instead of storing the category name repeatedly, the stylesheet looks up the matching category using the external XML document.
This reduces duplication and makes maintenance much easier.
Loading XML from URLs
The document() function can also load XML documents from web servers if supported by the XSLT processor.
Example:
document('https://example.com/products.xml')
This enables transformations using remotely hosted XML data. However, many modern processors restrict remote access for security reasons, so support depends on the execution environment.
Performance Considerations
Although the document() function is powerful, developers should use it carefully.
Some best practices include:
-
Avoid loading the same document repeatedly inside loops.
-
Store external documents in variables.
-
Keep XML files reasonably sized.
-
Use
xsl:keyfor fast searching in external documents. -
Minimize unnecessary XPath evaluations.
Loading a document once and reusing it improves transformation speed significantly.
Common Challenges
Missing XML File
If the specified XML file does not exist, the transformation may fail or return an empty node set depending on the processor.
Incorrect File Path
Relative paths must be correct with respect to the stylesheet location.
Example:
document('data/products.xml')
If the folder structure changes, the stylesheet may not locate the file.
Namespace Differences
If external XML files use namespaces, XPath expressions must include the appropriate namespace prefixes.
Large External Files
Loading extremely large XML documents can consume considerable memory and slow down transformations.
Best Practices
-
Store reusable reference data in separate XML files.
-
Load external documents once using variables.
-
Use meaningful filenames for external XML documents.
-
Combine the
document()function withxsl:keyfor efficient lookups. -
Validate external XML files before transformation.
-
Keep related XML documents organized in a clear directory structure.
-
Test file paths carefully when deploying to different environments.
Advantages
-
Combines multiple XML documents into a single transformation.
-
Encourages modular and reusable XML data organization.
-
Reduces data duplication.
-
Simplifies maintenance of large XML-based systems.
-
Supports dynamic loading of XML files.
-
Enables centralized reference and lookup data.
-
Produces richer and more comprehensive reports.
Limitations
-
Available primarily in XSLT 1.0 and 2.0, with evolving alternatives in later versions.
-
Performance may decrease when processing many large external documents.
-
File paths must be managed carefully.
-
Access to remote XML resources may be restricted by the processor or security settings.
-
Debugging becomes more complex when transformations rely on multiple interconnected XML files.
Conclusion
The document() function is a valuable feature in XSLT that allows stylesheets to access and combine information from multiple XML documents during a single transformation. It is particularly useful for joining related datasets, maintaining reusable lookup tables, and generating comprehensive reports without duplicating data. By organizing XML into separate, manageable files and using the document() function effectively, developers can create flexible, maintainable, and scalable XML transformation solutions.