wabg278
wabg278

Reputation: 13

XSLT Import Elements from Other File Matching ID Value in Both Files

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

Answers (1)

michael.hor257k
michael.hor257k

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

Related Questions