Jump to content

Extract details from another xml file in XSLT


tombliboo

Recommended Posts

HiI'm parsing a xml file through Saxon which generates the structure of my website in that it produces the relevant pages, however currently all my xsl:result-document code achieves is to output the title of the page and provide a link back to my index.What I now need to achieve is to extract the details of my products from a seperate xml file as relevant, a simplified copy of that file is below the real thing contains hundreds of records (please tell me its set out OK!).A few comments in terms of the schema, each product:Must have:<productid><title><price><image><desc><stock><incl ude>May not have:<imagelarge> (If missing don't show a link)<features>May have numerous:<features> (Display all in a list><include> (Display in multiple categories)The nodes to display on the page are:TitleImage (with link if <imagelarge> is available)TitlePriceStock (if in stock, a link/button 'buy')DescriptionFeatures (if available)Please help me my shop could be making me money! Anyone like toy cars by the way? ;) I know I know I'm doomed! ANY advice greatly appreciated.

<?xml version = "1.0" encoding = "UTF-8"?><catalog>	 <product>		  <productid>0001</productid>		  <title>Product 1</title>		  <price>2.99</price>		  <image>prod1.jpg</image>		  <imagelarge>prod1x.jpg</imagelarge>		  <desc>A description of product 1.</desc>		  <features>Prod1 feature</features>		  <features>Prod1 another feature</features>		  <stock>In Stock</stock>		  <include>					<category>This Category</category>					<subcategory>This Subcategory 1</subcategory>		  </include>		  <include>					<category>This Category</category>					<subcategory>This Subcategory 4</subcategory>		  </include>	 </product>	 <product>		  <productid>0002</productid>		  <title>Product 2</title>		  <price>1.99</price>		  <image>prod2.jpg</image>		  <imagelarge>prod2x.jpg</imagelarge>		  <desc>A description of product 2.</desc>		  <features>Prod2 only one feature</features>		  <stock>Out of Stock</stock>		  <include>					<category>That Category</category>					<subcategory>That Subcategory 3</subcategory>		  </include>	 </product></catalog>

Link to comment
Share on other sites

You can use XSLT's document() function to get data from another XML document. All you need to store in your main XML file is something by which you can find the file to load. For example, if each product's file is named after their ID (e.g. "0001.xml"), you can store just that in the main XML, and gather the details accordingly.

Link to comment
Share on other sites

All products are listed within the same xml file, so I've been working with the document() function and produced the following code, I'm trying to look into the xml file to search through all products and pull out information for those products which match the current subcategory webpage being generated.

<xsl:template match="/"><html><body><xsl:for-each select="document('products.xml')/catalog/product/include">	  <xsl:if test="subcategory='Diecast Cars'">	  <table>		<tr>		   <td><xsl:value-of select="/catalog/product/title"/></td>		</tr>	  </table>	  </xsl:if></xsl:for-each>	  </body></html></xsl:template>

This is returning:

<html>   <body>	  <table>		 <tr>			<td>Title1 Title2 Title3</td>		 </tr>	  </table>	  <table>		 <tr>			<td>Title1 Title2 Title3</td>		 </tr>	  </table>	  <table>		 <tr>			<td>Title1 Title2 Title3</td>		 </tr>	  </table>   </body></html>

I'm testing with just 3 products, each of them are to be included in the specified subcategory but as you can see all 3 product titles are being returned in each run.I'm reading about xsl:key, to return unique keys but struggling to apply it, is this the best option and if so how is it set, please help?

Link to comment
Share on other sites

It's not a good idea to keep hundreds of records into a single XML file. That's likely to quickly exsaust your computer's RAM, even when using SAXON. You should do a split IMMEDIATELY, while you still have the RAM for it.You can do the split with something like:

<xsl:template match="/*">	<xsl:for-each select="product">		<xsl:result-document href="{concat('products/', id,'.xml')}">			<xsl:copy-of select="." />		</xsl:result-document>	</xsl:for-each></xsl:template>

As for the rest of your problems... there's thing thing in XPath called predicates. Instead of looping over the "include" elements of your product, loop over all products that match certain predicate(s). XPath 2.0 (used in XSLT 2.0) actually allows you even more constructs not shown in the linked page, but the basic idea remains the same.

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...