I have two XML documents I need to merge.
<!-- A.xml -->
<cm:Process>
<cm:Other />
<cm:Elements />
<cm:Request>
<!-- stuff -->
</cm:Request>
<cm:ElementCouldBeHereToo />
<cm:Request>
<!-- stuff -->
</cm:Request>
</cm:Process>
<!-- B.xml -->
<gateway-orders>
<response>
<status />
</response>
<response>
<status />
</response>
</gateway-orders>
The first is the original XML. The requests has been pulled out and sent to a system and the next is the responses. Now I need to merge these two and match request N with response N so I can pull in some info from the responses. The XSL work on A.xml and get B.xml as a parameter. To begin with I’m just trying to create a copy of the correct response in B.xml inside the request in A.xml.
The problem I have is that I thought I could use position(), but realized that won’t work since the cm:Request elements are mixed with other elements. Is there another way I can use to match up these somehow?
This is what I tried:
<xsl:import href="identity-transform.xsl" />
<xsl:param name="responses" />
<xsl:template match="cm:Request">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
<xsl:apply-templates select="$responses/*[1]/*[position()]" />
</xsl:copy>
</xsl:template>
There are two problems here.
- First of all the
position()won’t match up. Is there a way to get the number/position ofcm:Requestelements you’re at rather than the number/position of all sibling elements? So that the firstcm:Requestalways gives 1 irregardless of if it has any elements in front of it. - Secondly I for some reason get a copy of all responses inside each request. If I change
position()with for example1, I only get a copy of the first response in each request. What am I doing wrong here?
Hoping someone knows what I should do here, cause I’m a bit blank right now and my Google-fu is failing me 😛
So to sum up, how can I match up the nth element with name blah with the nth child in a parameter node-set?
How’s this:
To explain this:
In this case,
position()is actually behaving differently from how you think it is. If you did this in that template:Then
$poswould have the position of the currentcm:Requestin relation to all of its siblings, but here:position()is being evaluated in the context$responses/*[1]/*. So for the first<response>this evaluates to$responses/*[1]/*[1]and for the second response, this evaluates to$responses/*[1]/*[2], hence both are always selected.