 |
| XSLT General questions and answers about XSLT. For issues strictly specific to the book XSLT 1.1 Programmers Reference, please post to that forum instead. |
Welcome to the p2p.wrox.com Forums.
You are currently viewing the XSLT section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
|
|
|
|

May 6th, 2012, 07:58 AM
|
|
Registered User
|
|
Join Date: May 2012
Posts: 6
Thanks: 2
Thanked 0 Times in 0 Posts
|
|
Error when creating multiple files
I'm trying to create different files from the names listed in an xml file. I've used key grouping in order to ensure that I don't repeat names which appear various times. However, when I execute the processor I get an error that seems to say that i'm trying to create the same file twice.
Here's the complete error :
Code:
Error at xsl:result-document on line 100 of generate-author-pages.xsl:
XTDE1490: Cannot write more than one result document to the same URI:
file:/C:/Users/aromanch/Dropbox/INFOH509%20-%20XML%20Technologies/Project%202%20-%20XSLT/M/Maulik.ujjwal.html
at xsl:call-template name="create-file-firstname" (file:/C:/Users/aromanch/Dropbox/INFOH509%20-%20XML%20Technologies/Project%202%20-%20XSLT/generate-author-pages.xsl#87)
at xsl:call-template name="create-file" (file:/C:/Users/aromanch/Dropbox/INFOH509%20-%20XML%20Technologies/Project%202%20-%20XSLT/generate-author-pages.xsl#80)
at xsl:call-template name="create-file" (file:/C:/Users/aromanch/Dropbox/INFOH509%20-%20XML%20Technologies/Project%202%20-%20XSLT/generate-author-pages.xsl#20)
at xsl:apply-templates (file:/C:/Users/aromanch/Dropbox/INFOH509%20-%20XML%20Technologies/Project%202%20-%20XSLT/generate-author-pages.xsl#15)
processing /dblp/incollection[7]/author[2]
at xsl:for-each (file:/C:/Users/aromanch/Dropbox/INFOH509%20-%20XML%20Technologies/Project%202%20-%20XSLT/generate-author-pages.xsl#14)
processing /dblp/incollection[7]/author[2]
; SystemID: file:/C:/Users/aromanch/Dropbox/INFOH509%20-%20XML%20Technologies/Project%202%20-%20XSLT/generate-author-pages.xsl; Line#: 100; Column#: -1
net.sf.saxon.trans.XPathException: Cannot write more than one result document to the same URI: file:/C:/Users/aromanch/Dropbox/INFOH509%20-%20XML%20Technologies/Project%202%20-%20XSLT/M/Maulik.ujjwal.html
at net.sf.saxon.instruct.ResultDocument.checkAcceptableUri(ResultDocument.java:548)
at net.sf.saxon.instruct.ResultDocument.processLeavingTail(ResultDocument.java:364)
at net.sf.saxon.instruct.Block.processLeavingTail(Block.java:619)
at net.sf.saxon.instruct.Template.expand(Template.java:246)
at net.sf.saxon.instruct.CallTemplate$CallTemplatePackage.processLeavingTail(CallTemplate.java:448)
at net.sf.saxon.instruct.ApplyTemplates.apply(ApplyTemplates.java:212)
at net.sf.saxon.instruct.ApplyTemplates.process(ApplyTemplates.java:170)
at net.sf.saxon.instruct.ForEach.processLeavingTail(ForEach.java:331)
at net.sf.saxon.instruct.Template.applyLeavingTail(Template.java:229)
at net.sf.saxon.instruct.ApplyTemplates.applyTemplates(ApplyTemplates.java:346)
at net.sf.saxon.Controller.transformDocument(Controller.java:1851)
at net.sf.saxon.Controller.transform(Controller.java:1702)
at XSLTRunner.convert(XSLTRunner.java:21)
at XSLTRunner.main(XSLTRunner.java:49)
Here's a sample of my xml file (which is much much longer) :
Code:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dblp SYSTEM "dblp.dtd">
<dblp>
<book mdate="2007-06-01" key="books/infix/Makoui2007">
<author>Mazeyar E. Makoui</author>
<title>Anfrageoptimierung in objektrelationalen Datenbanken durch kostenbedingte Termersetzungen</title>
<volume>100</volume>
<isbn>978-3-89838-500-8</isbn>
<year>2007</year>
<publisher>Aka Akademische Verlagsgesellschaft Aka GmbH, Berlin</publisher>
<series href="db/series/disdbis/index.html">DISDBIS</series>
</book>
<book mdate="2008-01-29" key="books/mitp/SaakeSH2008">
<author>Gunter Saake</author>
<author>Kai-Uwe Sattler</author>
<author>Andreas Heuer</author>
<title>Datenbanken: Konzepte und Sprachen, 3. Auflage</title>
<publisher>mitp-Verlag, Redline GmbH</publisher>
<year>2008</year>
<isbn>978-3-8266-1664-8</isbn>
<url>http://www.biberbuch.de</url>
</book>
<incollection mdate="2007-09-21" key="books/ws/BMW07-papers/ChoP07">
<author>Sung-Bae Cho</author>
<author>Han-Saem Park</author>
<title>Sophisticated Methods for Cancer Classification Using Microarray Data.</title>
<pages>281-302</pages>
<year>2007</year>
<crossref>books/ws/BMW07</crossref>
<booktitle>Analysis of Biological Data: A Soft Computing Approach</booktitle>
<url>db/books/collections/bmw07.html#ChoP07</url>
</incollection>
<incollection mdate="2007-09-21" key="books/ws/BMW07-papers/DebRC07">
<author>Kalyanmoy Deb</author>
<author>Abbadi Raji Reddy</author>
<author>Shamik Chaudhuri</author>
<title>A Reliable Classification of Gene Clusters for Cancer Samples Using a Hybrid Multi-Objective Evolutionary Procedure.</title>
<pages>231-257</pages>
<year>2007</year>
<crossref>books/ws/BMW07</crossref>
<booktitle>Analysis of Biological Data: A Soft Computing Approach</booktitle>
<url>db/books/collections/bmw07.html#DebRC07</url>
</incollection>
<inproceedings mdate="2008-01-24" key="conf/ACISicis/CaoED07">
<author>Tam Phuong Cao</author>
<author>Darrell M. Elton</author>
<author>John Devlin</author>
<title>Real-time Linear Projection Speed Sign Detection System in Low Light Conditions.</title>
<pages>332-338</pages>
<year>2007</year>
<crossref>conf/ACISicis/2007</crossref>
<booktitle>ACIS-ICIS</booktitle>
<ee>http://doi.ieeecomputersociety.org/10.1109/ICIS.2007.152</ee>
<url>db/conf/ACISicis/ACISicis2007.html#CaoED07</url>
</inproceedings>
<inproceedings mdate="2007-07-17" key="conf/ACISicis/YiH07">
<author>Li Yi</author>
<author>Ji Hong</author>
<title>A New Cooperative Communication MAC Strategy for Wireless Ad Hoc Networks.</title>
<pages>569-574</pages>
<year>2007</year>
<crossref>conf/ACISicis/2007</crossref>
<booktitle>ACIS-ICIS</booktitle>
<ee>http://doi.ieeecomputersociety.org/10.1109/ICIS.2007.34</ee>
<url>db/conf/ACISicis/ACISicis2007.html#YiH07</url>
</inproceedings>
and finally here's my xslt file :
Code:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<!--Initialize Output Methods-->
<xsl:output method="text"/>
<xsl:output method="html" indent="yes" name="html"/>
<!--Initialize Global variables-->
<xsl:variable name="capitals" select="'AZERTYUIOPQSDFGHJKLMWXCVBN'"/>
<xsl:variable name="smalls" select="'azertyuiopqsdfghjklmwxcvbn'"/>
<!--Initialize keys-->
<xsl:key name="authors" match="book/author" use="."/>
<xsl:key name="production" match="dblp/*" use="author"/>
<!--Root template-->
<xsl:template match="/">
<xsl:for-each select="//author[count(. | key('authors', .)[1]) = 1]">
<xsl:apply-templates select="."/>
</xsl:for-each>
</xsl:template>
<!--Author template-->
<xsl:template match="author">
<xsl:call-template name="create-file">
<xsl:with-param name="name" select="."/>
<xsl:with-param name="marker" select="' '"/>
</xsl:call-template>
</xsl:template>
<!--Retrieving author's first name-->
<xsl:template name="author-firstname">
<xsl:param name="name"/>
<xsl:param name="marker"/>
<xsl:if test="contains($name,$marker)">
<xsl:value-of select="substring-before($name,$marker)"/>
<xsl:value-of select="' '"/>
<xsl:call-template name="author-firstname">
<xsl:with-param name="name" select="substring-after($name, $marker)"/>
<xsl:with-param name="marker" select="' '"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
<!--retrieving author's last name-->
<xsl:template name="author-lastname">
<xsl:param name="name"/>
<xsl:param name="marker"/>
<xsl:choose>
<xsl:when test="contains($name,$marker)">
<xsl:call-template name="author-lastname">
<xsl:with-param name="name" select="substring-after($name, $marker)"/>
<xsl:with-param name="marker" select="' '"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$name"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!--Retrieving first letter of author's last name-->
<xsl:template name="author-lastname-first-letter">
<xsl:param name="name"/>
<xsl:param name="marker"/>
<xsl:choose>
<xsl:when test="contains($name,$marker)">
<xsl:call-template name="author-lastname">
<xsl:with-param name="name" select="substring-after($name, $marker)"/>
<xsl:with-param name="marker" select="' '"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$name"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!--First part of creating file-->
<xsl:template name="create-file">
<xsl:param name="name"/>
<xsl:param name="marker"/>
<xsl:choose>
<xsl:when test="contains($name,$marker)">
<xsl:call-template name="create-file">
<xsl:with-param name="name" select="substring-after($name, $marker)"/>
<xsl:with-param name="marker" select="' '"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="filename" select="concat(concat(substring($name,1,1),'\',''),$name,'.')" /> <!--filename is : "firstletter\lastname."-->
<xsl:call-template name="create-file-firstname">
<xsl:with-param name="name" select="normalize-space(translate(substring(.,1,string-length(.)-string-length($name)),$capitals,$smalls))"/> <!--Sending name without last name and with normalized spaces-->
<xsl:with-param name="file" select="$filename"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!--Final part of creating file-->
<xsl:template name="create-file-firstname">
<xsl:param name="name"/>
<xsl:param name="file"/>
<xsl:variable name="filename" select="concat($file,translate($name,' .-','_=='),'.html')"/> <!--filename is : "firstletter\lastname.firstname.html"-->
<xsl:result-document href="{$filename}" format="html">
<html>
<head><title>Publications of <xsl:value-of select="."/></title></head>
<body>
<h1>
<xsl:call-template name="author-lastname">
<xsl:with-param name="name" select="."/>
<xsl:with-param name="marker" select="' '"/>
</xsl:call-template>
<xsl:value-of select="' '"/>
<xsl:call-template name="author-firstname">
<xsl:with-param name="name" select="."/>
<xsl:with-param name="marker" select="' '"/>
</xsl:call-template>
</h1>
<xsl:for-each select="key('production', .)">
<p><xsl:value-of select="title"/></p>
</xsl:for-each>
</body>
</html>
</xsl:result-document>
</xsl:template>
</xsl:stylesheet>
Any help?
|
|

May 6th, 2012, 10:39 AM
|
|
Friend of Wrox
|
|
Join Date: Nov 2007
Posts: 1,243
Thanks: 0
Thanked 245 Times in 244 Posts
|
|
As you use XSLT 2.0 I would simply use xsl: for-each-group to eliminate duplicate authors instead of working with keys.
That might simplify the code.
It also appears the code extracting parts of the name could be simplified making use of the XSLT 2.0 xsl: analyze-string instruction or the XPath 2.0 tokenize function.
As for the error with the attempt to write the same file twice with one transformation, I am not able to identify the reason for that by reading your code snippets. If you need help debugging that then consider to post minimal but complete samples allowing us to reproduce the problem.
__________________
Martin Honnen
Microsoft MVP (XML, Data Platform Development) 2005/04 - 2013/03
My blog
|
|
The Following User Says Thank You to Martin Honnen For This Useful Post:
|
|
|

May 7th, 2012, 06:53 AM
|
|
Registered User
|
|
Join Date: May 2012
Posts: 6
Thanks: 2
Thanked 0 Times in 0 Posts
|
|
Well, I made minor changes according to your comments. Here's my new xsl file :
Code:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<!--Initialize Output Methods-->
<xsl:output method="text"/>
<xsl:output method="html" indent="yes" name="html"/>
<!--Initialize Global variables-->
<xsl:variable name="capitals" select="'AZERTYUIOPQSDFGHJKLMWXCVBN'"/>
<xsl:variable name="smalls" select="'azertyuiopqsdfghjklmwxcvbn'"/>
<!--Initialize keys-->
<xsl:key name="authors" match="author" use="."/>
<xsl:key name="production" match="dblp/*" use="author"/>
<!--Root template-->
<xsl:template match="/">
<xsl:for-each-group select="//author" group-by=".">
<xsl:value-of select="."/>
<xsl:apply-templates select="."/>
</xsl:for-each-group>
</xsl:template>
<!--Author template-->
<xsl:template match="author">
<xsl:call-template name="create-file">
<xsl:with-param name="name" select="."/>
<xsl:with-param name="marker" select="' '"/>
</xsl:call-template>
</xsl:template>
<!--Retrieving author's first name-->
<xsl:template name="author-firstname">
<xsl:param name="name"/>
<xsl:param name="marker"/>
<xsl:if test="contains($name,$marker)">
<xsl:value-of select="substring-before($name,$marker)"/>
<xsl:value-of select="' '"/>
<xsl:call-template name="author-firstname">
<xsl:with-param name="name" select="substring-after($name, $marker)"/>
<xsl:with-param name="marker" select="' '"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
<!--retrieving author's last name-->
<xsl:template name="author-lastname">
<xsl:param name="name"/>
<xsl:param name="marker"/>
<xsl:choose>
<xsl:when test="contains($name,$marker)">
<xsl:call-template name="author-lastname">
<xsl:with-param name="name" select="substring-after($name, $marker)"/>
<xsl:with-param name="marker" select="' '"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$name"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!--Retrieving first letter of author's last name-->
<xsl:template name="author-lastname-first-letter">
<xsl:param name="name"/>
<xsl:param name="marker"/>
<xsl:choose>
<xsl:when test="contains($name,$marker)">
<xsl:call-template name="author-lastname">
<xsl:with-param name="name" select="substring-after($name, $marker)"/>
<xsl:with-param name="marker" select="' '"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$name"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!--First part of creating file-->
<xsl:template name="create-file">
<xsl:param name="name"/>
<xsl:param name="marker"/>
<xsl:choose>
<xsl:when test="contains($name,$marker)">
<xsl:call-template name="create-file">
<xsl:with-param name="name" select="substring-after($name, $marker)"/>
<xsl:with-param name="marker" select="' '"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="filename" select="concat(concat(substring($name,1,1),'\',''),$name,'.')" /> <!--filename is : "firstletter\lastname."-->
<xsl:call-template name="create-file-firstname">
<xsl:with-param name="name" select="normalize-space(translate(substring(.,1,string-length(.)-string-length($name)),$capitals,$smalls))"/> <!--Sending name without last name and with normalized spaces-->
<xsl:with-param name="file" select="$filename"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!--Final part of creating file-->
<xsl:template name="create-file-firstname">
<xsl:param name="name"/>
<xsl:param name="file"/>
<xsl:variable name="filename" select="concat($file,translate($name,' .-','_=='),'.html')"/> <!--filename is : "firstletter\lastname.firstname.html"-->
<xsl:result-document href="{$filename}" format="html">
<html>
<head><title>Publications of <xsl:value-of select="."/></title></head>
<body>
<h1>
<xsl:call-template name="author-lastname">
<xsl:with-param name="name" select="."/>
<xsl:with-param name="marker" select="' '"/>
</xsl:call-template>
<xsl:value-of select="' '"/>
<xsl:call-template name="author-firstname">
<xsl:with-param name="name" select="."/>
<xsl:with-param name="marker" select="' '"/>
</xsl:call-template>
</h1>
<xsl:for-each select="key('production', .)">
<p><xsl:value-of select="title"/></p>
</xsl:for-each>
</body>
</html>
</xsl:result-document>
</xsl:template>
</xsl:stylesheet>
I didn't use analyze-string yet because i'm having trouble detecting the last word of the name. I tried using the regex [a-zA-Z\-]+$, \s[a-zA-Z\-]+$ and even .+$ but apparently it never detects anything. Any help for this?
If you want to try out for my main error, here's a link to my xml file : http://dl.dropbox.com/u/13990374/dblp-excerpt.xml
|
|

May 7th, 2012, 08:32 AM
|
|
Friend of Wrox
|
|
Join Date: Nov 2007
Posts: 1,243
Thanks: 0
Thanked 245 Times in 244 Posts
|
|
There is one author "BaoCang Ding" and one "Baocang Ding" and I think your code for grouping distinguishes them as unique respectively different names while later on when you create files names your code does some normalization to lower case letters (and/or the file system on the OS does not distinguish between lower and upper case letters in files names), so that seems to be one reason why the XSLT processor gives that error that the stylesheet tries to write twice to a file with a certain name "D/Ding.baocang.html".
So in your grouping code you need to make sure you group on the normalized names.
__________________
Martin Honnen
Microsoft MVP (XML, Data Platform Development) 2005/04 - 2013/03
My blog
|
|
The Following User Says Thank You to Martin Honnen For This Useful Post:
|
|
|

May 7th, 2012, 09:29 AM
|
|
Registered User
|
|
Join Date: May 2012
Posts: 6
Thanks: 2
Thanked 0 Times in 0 Posts
|
|
Totally worked, thanks! :D And do you have any idea for the regex? What I have already works but it would be better if I can simplify the code for readability. This is the xsl I use for testing it :
Code:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:variable name="capitals" select="'AZERTYUIOPQSDFGHJKLMWXCVBN'"/>
<xsl:variable name="smalls" select="'azertyuiopqsdfghjklmwxcvbn'"/>
<xsl:template match="/">
<xsl:apply-templates select="//author[.='José E. Gallardo']"/>
</xsl:template>
<xsl:template match="author">
<xsl:call-template name="create-filename">
<xsl:with-param name="name" select="translate(.,$capitals,$smalls)"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="create-filename">
<xsl:param name="name"/>
<xsl:analyze-string select="$name" regex=".+$">
<xsl:matching-substring>
<xsl:variable name="letter" select="substring(regex-group(1),1,1)"/>
<xsl:variable name="lastname" select="normalize-space(translate(regex-group(1),'.-','=='))"/>
<xsl:variable name="firstname" select="translate(normalize-space(substring($name,1,string-length($name)-string-length($lastname))),' .-','===')"/>
<xsl:variable name="temp-filename" select="concat($letter,'\',$lastname)"/>
<xsl:variable name="temp2-filename" select="concat($temp-filename,'.',$firstname)"/>
<xsl:variable name="filename" select="concat($temp2-filename,'.html','')"/>
<xsl:result-document href="{$filename}">
<xsl:value-of select="."/>
</xsl:result-document>
</xsl:matching-substring>
</xsl:analyze-string>
</xsl:template>
</xsl:stylesheet>
And here's a sample xml to test it with :
Code:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dblp SYSTEM "dblp.dtd">
<dblp>
<incollection mdate="2007-09-21" key="books/ws/BMW07-papers/GallardoCF07">
<author>José E. Gallardo</author>
<author>Carlos Cotta</author>
<author>Antonio J. Fernández</author>
<title>Reconstructing Phylogenies with Memetic Algorithms and Branch-and-Bound.</title>
<pages>59-84</pages>
<year>2007</year>
<crossref>books/ws/BMW07</crossref>
<booktitle>Analysis of Biological Data: A Soft Computing Approach</booktitle>
<url>db/books/collections/bmw07.html#GallardoCF07</url>
</incollection>
</dblp>
|
|

May 8th, 2012, 12:14 PM
|
|
Registered User
|
|
Join Date: May 2012
Posts: 6
Thanks: 2
Thanked 0 Times in 0 Posts
|
|
Anyone please?
|
|
 |