Reputation: 3
I am trying to replace relative links with absolute links where data is available in param.
Here is the xsl I am using.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:ext="http://exslt.org/common"
exclude-result-prefixes="#all">
<xsl:output method="html" encoding="UTF-8" omit-xml-declaration="yes" indent="no"/>
<xsl:param name="text1">
<span>Response from web service starts.<div>
<a href="http://www.google.com">Absolute Link</a>
Other stuff<a href="/link1">Relative Link</a></div>
Response from web service done.</span>
</xsl:param>
<xsl:template match="/">
<html>
<body>
<a href="http://www.gmail.com">Link in HTML</a>
<xsl:copy>
<xsl:apply-templates select="ext:node-set($text1)//a[@href[starts-with(.,'/')]]"/>
</xsl:copy>
</body>
</html>
</xsl:template>
<xsl:template match="a[@href[starts-with(.,'/')]]">
<xsl:attribute name="href">
<xsl:value-of select="concat('http://myserver',.)"/>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
This is the output I need.
<html>
<body>
<a href="http://www.gmail.com">Link in HTML</a>
<span>
Response from web service starts.
<div>
<a href="http://www.google.com">Absolute Link</a>
Other stuff
<a href="http://myserver/link1">Relative Link</a>
</div>
Response from web service done.
</span>
</body>
</html>
This xsl is not working. The input xml can be anything. I am wondering how the relative links in the parameter text1 can be replaced with absolute links and then rendered as html.
Any help is much appreciated. Thanks.
Upvotes: 0
Views: 223
Reputation: 167726
You need to process all nodes and you need to put in an identity transformation template to copy the nodes you don't want to transform. Furthermore set up the template for the href
attribute:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:ext="http://exslt.org/common"
exclude-result-prefixes="xs ext">
<xsl:output method="html" encoding="UTF-8" omit-xml-declaration="yes" indent="no"/>
<xsl:param name="text1">
<span>Response from web service starts.<div>
<a href="http://www.google.com">Absolute Link</a>
Other stuff<a href="/link1">Relative Link</a></div>
Response from web service done.</span>
</xsl:param>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/">
<html>
<body>
<a href="http://www.gmail.com">Link in HTML</a>
<xsl:copy>
<xsl:apply-templates select="ext:node-set($text1)/node()"/>
</xsl:copy>
</body>
</html>
</xsl:template>
<xsl:template match="a/@href[starts-with(.,'/')]">
<xsl:attribute name="href">
<xsl:value-of select="concat('http://myserver',.)"/>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
Note that your stylesheet had version="2.0"
but used the node-set
extension function so I assumed you want to solve that with an XSLT 1.0 processor where you need to use the node-set
function. If you really used an XSLT 2.0 processor then you can simplify <xsl:apply-templates select="ext:node-set($text1/node()"/>
to <xsl:apply-templates select="$text1/node()"/>
.
Upvotes: 1
Reputation: 2187
Instead of
<xsl:apply-templates select="ext:node-set($text1)//a[@href[starts-with(.,'/')]]"/>
you need a recursive copy and only modify the matching nodes
<xsl:apply-templates select="ext:node-set($text1)"/>
....
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
change the match of your <xsl:template match="a[@href[starts-with(.,'/')]]">
template to
<xsl:template match="@href[starts-with(.,'/')]">
and then
Upvotes: 0