Wrox Programmer Forums
Go Back   Wrox Programmer Forums > XML > XSLT
|
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
 
Old March 23rd, 2006, 02:19 PM
Authorized User
 
Join Date: Jan 2006
Posts: 14
Thanks: 0
Thanked 0 Times in 0 Posts
Default Analyze XML doc using XSLT

Hi,

Using my computer example, I want to use XSLT to figure out when to take my computer for servicing. My example doc is show below

Code:
<computer name="DELL XPS" service-year="2005">
   <component number="1" name="chassis">
      <expected-life years="6"/>
      <description>some chasis description</description>
   </component>
   <component number="2" name="hard-disk">
      <expected-life years="4"/>
      <description>some hard-disk description</description>
   </component>
   <component number="5" name="screen">
      <expected-life years="3"/>
      <description>some screen description</description>
   </component>
   <component number="4" name="keyboard">
      <expected-life years="3"/>
      <description>some keyboard description</description>
   </component>
   <component number="5" name="usb">
      <expected-life years="5"/>
      <description>some usb description</description>
   </component>
   <component number="6" name="mic">
      <expected-life years="2"/>
      <description>some keyboard description</description>
   </component>
   <component number="5" name="mouse">
      <expected-life years="1"/>
      <description>some usb description</description>
   </component>
</computer>
With my XSLT stylesheet, I want to ensure that I take the computer for repair if two or more parts have surpassed their expected life span(given by expected-life attribute). My document node has a service-year attribute to indicate when the computer was last service.

Therefore, I want to somehow go through the whole XML document and retrieve all the @years attributes(from the expected-life element) into a node set.

Then I want to be able to say when to take the PC for servicing once I find the two components that will fail first.

To this effect I am trying to write the stylesheet below but I am stuck. I am wondering if I am on the correct path.

Code:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
   <xsl:output method="html"/>
   <xsl:variable name="maxFailed">2</xsl:variable>
   <xsl:template match="computer">
      <xsl:apply-templates/>
   </xsl:template>
   <xsl:template match="component">
      <xsl:apply-templates/>
   </xsl:template>
   <xsl:template match="expected-life">
      part will fail after: <xsl:value-of select="@years"/> years
      <br/>
   </xsl:template>

   <xsl:template match="@* | node()"/>
</xsl:stylesheet>
Evidently, my stylesheet is incomplete as I am still working on it. I was wondering if I am on the right path. I think if I can get all the @years into a node set and then sort it, I can then just get the third entry in the node set and that the number of years after the last service date when my computer will fail.



Kind Regards,
Shumba
__________________
Kind Regards,
Shumba
 
Old March 23rd, 2006, 02:54 PM
mhkay's Avatar
Wrox Author
 
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
Default

 I want to ensure that I take the computer for repair if two or more parts have surpassed their expected life span

with <computer> as context node:

<xsl:if test="count(component[expected-life/@years + ../service-year > $this-year])">
  take it for repair
</xsl:if>

You're trying to do it procedurally, whereas this is a clear case for a declarative approach.

Michael Kay
http://www.saxonica.com/
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference
 
Old March 23rd, 2006, 03:06 PM
Authorized User
 
Join Date: Jan 2006
Posts: 14
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Thanks for the help. I will try to do that.

The other issue is I am using XSLT 1.0 and do not have the current year($this-year) to hand. I guess I can use global variable or pass to the Stylesheet. Is there a way to get the current date in XSLT 1.0? I am aware this can be done in XSLT 2.0

I have been programming in C/C++/Java/Perl for ages and I just picked up XML/XSL about a month ago so I guess I am still wired to procedural gremlins.
 
Old March 23rd, 2006, 03:54 PM
Authorized User
 
Join Date: Jan 2006
Posts: 14
Thanks: 0
Thanked 0 Times in 0 Posts
Default

ok. I had to correct the predicate to use ../@service-year.

Above this, I need to be able to say when I need to take for repair.
 
Old March 23rd, 2006, 06:52 PM
mhkay's Avatar
Wrox Author
 
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
Default

The simplest way to get current date/year in XSLT 1.0 is to pass it as a stylesheet parameter (except possibly in client-side environments where calling Javascript might be easier).

Check whether your processor supports the EXSLT date/time extensions (www.exslt.org).

Michael Kay
http://www.saxonica.com/
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference
 
Old March 24th, 2006, 05:19 PM
Authorized User
 
Join Date: Jan 2006
Posts: 14
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Thanks Micheal for your input.

I will venture into EXSLT to find out about the date/time support. I am doing something general purpose and I am not confident the client will have a processor that supports EXSLT. I will however go ahead and find out if they will.



I realised that I do not need to know the current date - I just need to be able to tell when the computer will fail.

If I know the last service date, then I can know when to take my computer for service when the third component exceeds it's expected life. So I sorted the components based on their expected life and the third entry in the node set will be how long from the service date the computer will need before it fails.

Stylesheet below.

Code:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
   <xsl:output method="html"/>
   <xsl:variable name="fail-index">3</xsl:variable>
   <xsl:template match="computer">
      <xsl:apply-templates select="component">

         <xsl:sort data-type="number" select="expected-life/@years"/>
      </xsl:apply-templates>
   </xsl:template>

   <xsl:template match="component">
      <!-- The components are sorted so we the computer will fail if ($fail-index -1) have failed. 
            The $fail-index position therefore gives as the first component that will require the computer
            to be taken for service-->
      <xsl:if test="position() = $fail-index"> The <xsl:value-of select="../@name"/> computer will
         fail in <xsl:value-of select="expected-life/@years + ancestor::node()
            /@service-year"/>
      </xsl:if>
      <xsl:apply-templates select="expected-life"/>
   </xsl:template>
</xsl:stylesheet>
If there is a better way to do this please advise.





Similar Threads
Thread Thread Starter Forum Replies Last Post
Creating XML doc ; writing string(xml format) into KamalRaturi XML 5 May 28th, 2008 05:51 AM
Can 1 xslt transform an xml doc into 2 text files Raju Sarode XSLT 7 November 3rd, 2006 04:10 PM
Pull and Assign XSLT Parameter from ASPX Doc kwilliams ASP.NET 2.0 Basics 0 October 20th, 2006 11:35 AM
Help making a doc using XML topshed XML 2 January 28th, 2006 08:05 PM
whole database to XML doc beyondforsaken VB How-To 4 June 11th, 2003 08:12 PM





Powered by vBulletin®
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
Copyright (c) 2020 John Wiley & Sons, Inc.