Using XSLT To Combine Data from Parallel Nodes

Here should go questions about transforming XML with XSLT and FOP.
StephenGunn
Posts: 1
Joined: Wed Mar 27, 2019 12:52 am

Using XSLT To Combine Data from Parallel Nodes

Post by StephenGunn » Wed Mar 27, 2019 1:08 am

Is it possible to take a value from one node in xml, attributes always in this particular xml, and find that value in a key pair, id=2 for example, and take information from the node with id=2 and combine it with information from the original node. All with the objective to make it easier to read in an xml reader, to better decipher the data.

So, to clear that up here is a simple example:

<xml ...>

<MyNode1>
<Brick ID = "2", Color = "red", Material = "Clay">
<SomeOtherTag attribute1="build"/>
</Brick>
<Brick ID = "3", Color = "black", Material = "Clay">
<SomeOtherTag attribute1="build"/>
</Brick>

</MyNode1>
<PartsOfHouse>
<House ID="1", Brick="2", Yada="3", Yada2="big" />
<House ID="2", Brick="3", Yada="3", Yada2="big" />
</PartsOfHouse>


Run through XSLT ....

<PartsOfHouse>
<House ID="1", Brick="2", Color = "red", Yada="3", Yada2="big" />
<House ID="2", Brick="3", Color = "black", Yada="3", Yada2="big" />
</PartsOfHouse>

adrian
Posts: 2578
Joined: Tue May 17, 2005 4:01 pm

Re: Using XSLT To Combine Data from Parallel Nodes

Post by adrian » Wed Mar 27, 2019 12:13 pm

Hi,

You can use a copy stylesheet that intercepts the attribute @Brick from House (House/@Brick). After copying the attribute itself, make a copy of the corresponding Brick/@Color attribute (//Brick[@ID=$id]/@Color)

Code: Select all

<?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"/>

<xsl:template match="PartsOfHouse">
<xsl:apply-templates select="." mode="copy"/>
</xsl:template>

<xsl:template match="House/@Brick" mode="copy">
<xsl:variable name="id" select="."/>
<xsl:copy>
<xsl:apply-templates select="." mode="copy"/>
</xsl:copy>
<xsl:copy-of select="//Brick[@ID=$id]/@Color"/>
</xsl:template>

<xsl:template match="node() | @*" mode="copy">
<xsl:copy>
<xsl:apply-templates select="node() | @*" mode="copy"/>
</xsl:copy>
</xsl:template>

<!-- Handle default matching -->
<xsl:template match="text()"/>

</xsl:stylesheet>
If you want to copy everything, not just PartsOfHouse, change <xsl:template match="PartsOfHouse"> to <xsl:template match="/">.

Regards,
Adrian
Adrian Buza
<oXygen/> XML Editor, Schema Editor and XSLT Editor/Debugger
http://www.oxygenxml.com

Post Reply