Reputation: 2884
I am currently trying to use XSLT to convert some XML pseudo-code to a rest response result
For example, with the following xml:
<?xml version="1.0" encoding="UTF-8"?>
<root xmlns:functions="http://foo.com/api/rest">
<item bar="foo">some item</item>
<functions:fetch a="3" b="foo" />
</root>
And if the result of http://foo.com/services/rest/fetch/a/3/b/foo
is:
<?xml version="1.0" encoding="UTF-8"?>
<rsp stat="ok">
<book>
<title>Ethics</title>
</book>
<book>
<title>Beyond Good and Evil</title>
</book>
</rsp>
The result of the XSLT parsing I am trying to obtain is:
<?xml version="1.0" encoding="UTF-8"?>
<root xmlns:functions="http://foo.com/api/rest">
<item bar="foo">some item</item>
<book>
<title>Ethics</title>
</book>
<book>
<title>Beyond Good and Evil</title>
</book>
</root>
I know I can use <xsl:value-of select="document('http://foo.com/services/rest/fetch/a/3/b/foo')"/>
to make the request, but I am stuck on how to generate and process it in the same XSLT.
Any help will be greatly appreciated, Thanks in advance!
Upvotes: 1
Views: 3516
Reputation: 2884
Thanks to the answer from Dimitre, I found a solution!
(I make a new reply as I tuned Dimitre solution a little to work with any function name and multiple functions in the same XML)
Here the xslt:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:functions="http://foo.com/api/rest"
exclude-result-prefixes="functions">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="functions:*">
<xsl:variable name="request_function">
<xsl:value-of select="local-name(.)"/>
</xsl:variable>
<xsl:variable name="request_parameters">
<xsl:for-each select="@*">
<xsl:value-of select="concat('/', name(), '/', .)"/>
</xsl:for-each>
</xsl:variable>
<xsl:variable name="rest_response" select="document(concat('http://foo.com/services/rest/', $request_function, $request_parameters) )"/>
<xsl:apply-templates select="$rest_response/*/node()"/>
</xsl:template>
</xsl:stylesheet>
Thanks!
Upvotes: 0
Reputation: 243489
Here is one possible pure XSLT 1.0 solution:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:functions="http://foo.com/api/rest"
exclude-result-prefixes="functions">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="vDynPart">
<xsl:for-each select="/*/functions:*/@*">
<xsl:value-of select="concat('/', name(), '/', .)"/>
</xsl:for-each>
</xsl:variable>
<xsl:variable name="vRes" select=
"document(concat('http://foo.com/services/rest/fetch',
$vDynPart)
)"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
<xsl:apply-templates select="$vRes/*/node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="functions:*"/>
</xsl:stylesheet>
Upvotes: 2