Reputation: 13
I am having a problem including elements from a second XML file and need suggestions for proper XSLT Template code.
My first input file (the one being processed with xsltproc (XSLT 1.0) on a Ubuntu computer is (this test file has only one "entry" element to keep it short):
<?xml version="1.0" encoding="UTF-8"?>
<tellico>
<collection title="My Videos" type="3">
<entry id="1002">
<title>Midsomer Murders -- Set 25</title>
<id>1002</id>
<comments>Includes bonus material</comments>
<year>2013</year>
<cover>file:///data/www/htdocs/videodb/cache/img/1002.jpg</cover>
<running-time>90</running-time>
<medium>DVD</medium>
<genres></genres>
<set>Yes</set>
<count>3</count>
<location>2</location>
</entry>
</collection>
</tellico>
The second input file contains the elements I need to add in the output as children of the "genres" element, but all I need is the "name" element.
<?xml version="1.0" encoding="UTF-8"?>
<ooo_calc_export scriptVersion="2.2.0_qdxml" scriptUpdate="2011-03-02" scriptURL="http://www.digitalimprint.com/misc/oooexport/" scriptAuthor="vjl">
<ooo_sheet num="1">
<video_genre><id>1001</id><name>Crime</name></video_genre>
<video_genre><id>1001</id><name>Drama</name></video_genre>
<video_genre><id>1001</id><name>Mystery</name></video_genre>
<video_genre><id>1002</id><name>Crime</name></video_genre>
<video_genre><id>1002</id><name>Drama</name></video_genre>
<video_genre><id>1002</id><name>Mystery</name></video_genre>
<video_genre><id>1003</id><name>Adventure</name></video_genre>
<video_genre><id>1003</id><name>Drama</name></video_genre>
<video_genre><id>1003</id><name>Sci-Fi</name></video_genre>
<video_genre><id>1004</id><name>Drama</name></video_genre>
<video_genre><id>1004</id><name>History</name></video_genre>
<video_genre><id>1005</id><name>Action</name></video_genre>
<video_genre><id>1005</id><name>Adventure</name></video_genre>
<video_genre><id>1005</id><name>Drama</name></video_genre>
<video_genre><id>1005</id><name>War</name></video_genre>
<video_genre><id>1006</id><name>Documentary</name></video_genre>
<video_genre><id>1007</id><name>Crime</name></video_genre>
<video_genre><id>1008</id><name>Comedy</name></video_genre>
<video_genre><id>1008</id><name>Drama</name></video_genre>
<video_genre><id>1009</id><name>Drama</name></video_genre>
<video_genre><id>1010</id><name>Adventure</name></video_genre>
<video_genre><id>1010</id><name>Comedy</name></video_genre>
<video_genre><id>1010</id><name>Crime</name></video_genre>
</ooo_sheet>
</ooo_calc_export>
The Transform I have currently (not working) is:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- establish file path to XML file with Genre data -->
<xsl:variable name="genre-doc" select="document('genres.xml')"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="genres">
<!-- save current entry's id value -->
<xsl:variable name="video-id" select="../id/text()"/>
<!-- <current-video-id><xsl:value-of select="$video-id" /></current-video-id> DEBUG Only -->
<genres>
<!-- Fetch 'video_genre' elements from external file -->
<xsl:variable name="genre-info" select="document($genre-doc)/ooo_calc_export/ooo_sheet/video_genre[id=$video-id]/." />
<xsl:for-each select="$genre-info/*">
<genre><xsl:value-of select="name" /></genre>
Genre data goes here
</xsl:for-each>
</genres>
</xsl:template>
</xsl:stylesheet>
I am getting an error related to reading the second file:
$ xsltproc -o output-genre.xml transform-genre.xslt test-input-genre.xml
warning: failed to load external entity "1001Crime1001Drama1001Mystery1002Crime1002Drama1002Mystery1003Adventure1003Drama1003Sci-Fi1004Drama1004History1005Action1005Adventure1005Drama1005War1006Documentary1007Crime1008Comedy1008Drama1009Drama1010Adventure1010Comedy1010Crime"
It seems the second file is being accessed but is not getting what I want. It seems to be getting the Text values (not XML Elements) for the entire file. I want only the elements with "id" matching the "video-id" from which I will be using only the value of the "name" element. Probably a mistake with the XPATH.
My desired output is as shown in this file:
<tellico>
<collection title="My Videos" type="3">
<entry id="1002">
<title>Midsomer Murders -- Set 25</title>
<id>1002</id>
<comments>Includes bonus material</comments>
<year>2013</year>
<cover>file:///data/www/htdocs/videodb/cache/img/1002.jpg</cover>
<running-time>90</running-time>
<medium>DVD</medium>
<genres>
<genre>Crime</genre>
<genre>Drama</genre>
<genre>Mystery</genre>
</genres>
<set>Yes</set>
<count>3</count>
<location>2</location>
</entry>
</collection>
</tellico>
Any help is welcome - Thanks.
Upvotes: 1
Views: 1075
Reputation: 117100
The error you are getting is due to your reusing the document()
function when defining the genre-info
variable:
<xsl:variable name="genre-info" select="document($genre-doc)/ooo_calc_export/ooo_sheet/video_genre[id=$video-id]/." />
You have already used the document()
function when defining the genre-doc
variable:
<xsl:variable name="genre-doc" select="document('genres.xml')"/>
so now you're feeding the entire contents of the external XML file as the argument to the document()
function - and this of course results in failure.
Try defining the genre-info
variable as:
<xsl:variable name="genre-info" select="$genre-doc/ooo_calc_export/ooo_sheet/video_genre[id=$video-id]"/>
and then:
<xsl:for-each select="$genre-info">
<genre><xsl:value-of select="name" /></genre>
</xsl:for-each>
Upvotes: 2