Yes, you can “join” two XML documents to create one with merged data, and it’s actually easier than you might think. I’ll provide a simple example with a “parent” document and a “child” document.
We’ll use the <xsl:merge>
instruction, which is specifically designed for merging documents in XSLT 3.0.
Here’s a step-by-step example:
Input XML Files
Employee Master File (employees.xml
)
<employees>
<employee>
<id>1</id>
<hourly-rate>20</hourly-rate>
</employee>
<employee>
<id>2</id>
<hourly-rate>25</hourly-rate>
</employee>
</employees>
Labor Hours File (hours.xml
)
<labor>
<entry>
<id>1</id>
<date>2024-10-01</date>
<hours>8</hours>
</entry>
<entry>
<id>1</id>
<date>2024-10-02</date>
<hours>7</hours>
</entry>
<entry>
<id>2</id>
<date>2024-10-01</date>
<hours>6</hours>
</entry>
</labor>
Desired Output
The resulting XML should contain:
- Employee ID
- Total hours worked
- Hourly rate
- Total earnings (total hours * hourly rate)
XSLT Code (Version 3)
<xsl:stylesheet version="3.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- Load both input files using xsl:merge -->
<xsl:merge>
<xsl:merge-source select="doc('employees.xml')/employees/employee"
primary="true">
<xsl:merge-key select="id"/>
</xsl:merge-source>
<xsl:merge-source select="doc('hours.xml')/labor/entry">
<xsl:merge-key select="id"/>
</xsl:merge-source>
</xsl:merge>
<xsl:template match="xsl:merge">
<employees-summary>
<xsl:for-each-group select="current-group()" group-by="id">
<employee>
<id><xsl:value-of select="current-grouping-key()"/></id>
<total-hours>
<xsl:value-of select="sum(current-group()/hours)"/>
</total-hours>
<hourly-rate>
<xsl:value-of select="(current-group()/hourly-rate)[1]"/>
</hourly-rate>
<total-earnings>
<xsl:value-of select="sum(current-group()/hours)
* (current-group()/hourly-rate)[1]"/>
</total-earnings>
</employee>
</xsl:for-each-group>
</employees-summary>
</xsl:template>
</xsl:stylesheet>
Explanation:
- xsl:merge: Combines the two XML sources (
employees.xml
andhours.xml
) by matching theid
field from both. - xsl:for-each-group: Groups the entries by
id
, so we can sum up the hours worked for each employee. - sum(): Calculates the total hours worked for each employee.
- total-earnings: Multiplies the total hours worked by the employee’s hourly rate to compute earnings.
This XSLT will output the merged XML file with the total hours worked, hourly rate, and total earnings for each employee.