Reputation: 601
I have been facing with an issue for few days;
The problem is; I can't match with values inside the template from another template recursively.
Lets assume that we have an example: ...
<book>
<title>Alice in Wonderland</title>
<owner>LEWIS CARROLL</owner>
<numberID>1234</numberID>
</book>
...
This code block has many other siblings and parent nodes as well.
<Response>
<ID>1234</ID>
<name>Jose</name>
<feedback id="1">It is a good book</feedback>
<Response>
What i want is , get the feedback value from and write it to under book after the such as:
<book>
<title>Alice in Wonderland</title>
<owner>LEWIS CARROLL</owner>
<numberID>1234</numberID>
<feedback>It is a good book</feedback>
</book>
...."for some other nodes other feedbacks" etc
in XSLT i try:
<xsl:template match="book">
<xsl:param name="bookID" select="numberID"/>
<xsl:param name=responseID" select="ancestor::*/Response/ID"/>
<xsl:apply-templates/>
<xsl:choose>
<xsl:when test="$bookID=$numberID">
<xsl:if test="//Response/feedback[@feedbackID="1"]>
<feedback>
<xsl:copy-of select="//Response/feedback">
<feedback>
</xsl:if>
</xsl:when>
<xsl:choose>
So, please remember the structure is re-created with basic examples. The problem here the output of function are the all elements of node. I want the algorithm to put values recursively into corresponding nodes. but i dont know how to call the other template inside the current one with recursively. I hope that i managed to describe the problem well.
Upvotes: 0
Views: 80
Reputation: 52888
Another option is to create an xsl:key
that matches feedback
and uses the ID
from the parent Response
.
That will allow you to reference the key using numberID
from book
.
Example...
XML Input
<doc>
<books>
<book>
<title>Alice in Wonderland</title>
<owner>LEWIS CARROLL</owner>
<numberID>1234</numberID>
</book>
</books>
<responses>
<Response>
<ID>1234</ID>
<name>Jose</name>
<feedback id="1">It is a good book</feedback>
</Response>
</responses>
</doc>
XSLT 2.0 (Also works as XSLT 1.0)
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="feedback" match="Response/feedback" use="../ID"/>
<!--Identity transform-->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="book">
<xsl:copy>
<xsl:apply-templates select="@*|node()|key('feedback',numberID)"/>
</xsl:copy>
</xsl:template>
<!--Optional:
Remove responses element and remove id attribute from feedback element.-->
<xsl:template match="responses|feedback/@id"/>
</xsl:stylesheet>
Output
<doc>
<books>
<book>
<title>Alice in Wonderland</title>
<owner>LEWIS CARROLL</owner>
<numberID>1234</numberID>
<feedback>It is a good book</feedback>
</book>
</books>
</doc>
Working fiddle: http://xsltfiddle.liberty-development.net/pPgCcoz
Upvotes: 1
Reputation: 29052
I used these XML as a starting point:
<book>
<title>Alice in Wonderland</title>
<owner>LEWIS CARROLL</owner>
<numberID>1234</numberID>
</book>
... and ...
<Response>
<ID>1234</ID>
<name>Jose</name>
<feedback id="1">It is a good book</feedback>
</Response>
I tried to change your XSLT as little as possible, because the whole structure was not obvious for me. This is the result for which XSLT-1.0 suffices.
XSLT-1.0:
<!-- identity template -->
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*" />
</xsl:copy>
</xsl:template>
<xsl:template match="book">
<xsl:param name="bookID" select="numberID"/>
<xsl:param name="response" select="//Response[ID = $bookID]"/>
<xsl:copy>
<xsl:apply-templates />
<xsl:choose>
<xsl:when test="$response"> <!-- if Response with bookID exists... -->
<xsl:if test="$response/feedback[@id='1']"> <!-- if feedback with id 1 exists... -->
<feedback>
<xsl:value-of select="$response/feedback" /> <!-- copy only the value and not the whole content -->
</feedback>
</xsl:if>
</xsl:when>
</xsl:choose>
</xsl:copy>
</xsl:template>
Output:
<book>
<title>Alice in Wonderland</title>
<owner>LEWIS CARROLL</owner>
<numberID>1234</numberID>
<feedback>It is a good book</feedback>
</book>
<Response>
<ID>1234</ID>
<name>Jose</name>
<feedback id="1">It is a good book</feedback>
</Response>
Upvotes: 0