Reputation: 1
I have the problem with xslt. How to exactly use template to build output like this? I get tired already a long time with this, and it is problematic to use a tag xmlns
<?xml version="1.0" encoding="utf-8"?>
<books xmlns="http://example.net/books/1.0" xmlns:a="http://example.net/author/1.0">
<book>
<a:author>
<a:name>John</a:name>
<a:surname>Applesed</a:surname>
</a:author>
<title>Missing opportunity</title>
</book>
<book>
<a:author>
<a:name>Paul</a:name>
<a:surname>Morgan</a:surname>
</a:author>
<title>Test Book</title>
</book>
</books>
So far I was able to do something like this:
<?xml version='1.0' ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:b="http://example.net/library/1.0" >
<xsl:template match="/">
<books>
<xsl:for-each select="b:library/b:books/b:book">
<book>
<author>
<name>
<xsl:value-of select="../../b:authors/b:author/b:name"/>
</name>
<surname>
<xsl:value-of select="../../b:authors/b:author/b:surname"/>
</surname>
</author>
<title>
<xsl:value-of select="b:title"/>
</title>
</book>
</xsl:for-each>
</books>
</xsl:template>
</xsl:stylesheet>
Starting file is: This file cannot be edited
<?xml version="1.0" encoding="utf-8"?>
<library xmlns="http://example.net/library/1.0">
<authors>
<author id="a1">
<name>John</name>
<surname>Applesed</surname>
<born>1979-11-11</born>
</author>
<author id="a2">
<name>Chris</name>
<surname>Pattern</surname>
<born>1965-12-12</born>
</author>
<author id="a3">
<name>Paulo</name>
<surname>Coelho</surname>
<born>1915-06-17</born>
</author>
<author id="a4">
<name>Paul</name>
<surname>Morgan</surname>
<born>1473-02-19</born>
<died>1543-05-24</died>
</author>
</authors>
<books>
<book id="b1" author-id="a1">
<title>Missing opportunity</title>
<published>1992</published>
<isbn>978-3-16-148410-0</isbn>
</book>
<book id="b2" author-id="a4">
<title>Test Book</title>
<published>1543</published>
</book>
</books>
</library>
Upvotes: 0
Views: 88
Reputation: 116993
Try it this way:
XSLT1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:b="http://example.net/library/1.0"
xmlns:a="http://example.net/author/1.0"
exclude-result-prefixes="b">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="author" match="b:author" use="@id" />
<xsl:template match="/b:library">
<books xmlns="http://example.net/books/1.0">
<xsl:for-each select="b:books/b:book">
<xsl:variable name="author" select="key('author', @author-id)" />
<book>
<a:author>
<a:name>
<xsl:value-of select="$author/b:name"/>
</a:name>
<a:surname>
<xsl:value-of select="$author/b:surname"/>
</a:surname>
</a:author>
<title>
<xsl:value-of select="b:title"/>
</title>
</book>
</xsl:for-each>
</books>
</xsl:template>
</xsl:stylesheet>
Note the use of a key to resolve the cross-references to authors. This has nothing to do with the namespace issues, but it's more efficient this way.
Upvotes: 0
Reputation: 9481
You are not constraining your authors when preparing output records. Also ../.. are useless in this context. Use something like this
<xsl:value-of select="//b:authors[@id = ./@author-id ]/b:author/b:name"/>
Upvotes: 1