I have the following XML that I want to transform by XSLT. My main purpose is to have a list of urls only. It means any line that contains "http:// ".
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<urlset xmlns="http://www.google.com" xmlns:image="http://www.google1.com" xmlns:video="http://www.google2.com" xmlns:xhtml="http://www.google3.com">
<url>
<loc id="837">http://url1</loc>
</url>
<url>
<loc id="2332">http://url2</loc>
<image:image>
<image:loc>http://url3</image:loc>
</image:image>
<image:image>
<image:loc>http://url4</image:loc>
</image:image>
</url>
</urlset>
I created an XSLT as the following;
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml"
doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN"
doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"/>
<xsl:template match="/">
<html>
<body>
<h1>URLS</h1>
<ul>
<xsl:for-each select="urlset/url">
<li>
<xsl:value-of select="loc"/>
</li>
</xsl:for-each>
<xsl:for-each select="urlset/url/image:image">
<li>
<xsl:value-of select="image:loc"/>
</li>
</xsl:for-each>
</ul>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
The first foreach does not return anything and the second foreach gives exception like:
SystemId Unknown; Line #15; Column #53; Prefix must resolve to a namespace: image
Could anybody help why this XSLT fails ?
To resolve the immediate error, add a namespace definition of the image
namespace prefix to your stylesheet:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:image="http://www.google.com">
There are a number of other adjustments that will be required once you eliminate that error. It makes no sense to define so many namespace prefixes in your XML for the same (dubious) namespace.
Something like the following input XML would be more reasonable:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<urlset xmlns="http://www.example.com/urlset"
xmlns:image="http://www.example.com/image">
<url>
<loc id="837">url1</loc>
</url>
<url>
<loc id="2332">url2</loc>
<image:image>
<image:loc>url3</image:loc>
</image:image>
<image:image>
<image:loc>url4</image:loc>
</image:image>
</url>
</urlset>
Then, the following XSLT,
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:u="http://www.example.com/urlset"
xmlns:image="http://www.example.com/image"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/u:urlset">
<html>
<body>
<h1>URLS</h1>
<ul>
<xsl:for-each select="u:url">
<li>
<xsl:value-of select="u:loc"/>
</li>
</xsl:for-each>
<xsl:for-each select="u:url/image:image">
<li>
<xsl:value-of select="image:loc"/>
</li>
</xsl:for-each>
</ul>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
will yield the URL list you seek:
<html xmlns:u="http://www.example.com/urlset" xmlns:image="http://www.example.com/image">
<body>
<h1>URLS</h1>
<ul>
<li>url1</li>
<li>url2</li>
<li>url3</li>
<li>url4</li>
</ul>
</body>
</html>
You also might consider using a template-match-based organization of your XSLT rather than a loop-based organization as a matter of style. For a small example such as this, there's little difference in complexity, but for a larger problem, match-based organization is cleaner and clearer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With