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 19th, 2006, 09:21 AM
Authorized User
 
Join Date: Jan 2006
Posts: 14
Thanks: 0
Thanked 0 Times in 0 Posts
Default Validate dependencies using Schema/XSLT

Suppose I have the following XML instance document.

Code:
<computer>
   <component number="78" name="chassis">
      <related-to>79</related-to>
      <related-to>80</related-to>
   </component>
   <component number="79" name="hard-disk">
      <related-to>80</related-to>
   </component>
   <component number="80" name="screen">
      <related-to>78</related-to>
   </component>
</computer>
I need to validate that every related-to text content refers to an existing number attribute i.e. all components should relate to existing components.

Now I can do this very well in my XML Schema and I have tested and it works ok. The XML Schema is as follows

Code:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

   <xs:element name="computer">
      <xs:complexType>
         <xs:sequence>
            <xs:element name="component" type="partType" maxOccurs="unbounded"/>
         </xs:sequence>
      </xs:complexType>

      <xs:key name="key">
         <xs:selector xpath="component"/>
         <xs:field xpath="@number"/>
      </xs:key>

      <xs:keyref name="numKey" refer="key">
         <xs:selector xpath="component/related-to"/>
         <xs:field xpath="."/>
      </xs:keyref>
   </xs:element>

   <xs:complexType name="partType">
      <xs:sequence>
         <xs:element name="related-to" type="xs:positiveInteger" maxOccurs="unbounded"/>
      </xs:sequence>
      <xs:attribute name="name" type="xs:token" use="required"/>
      <xs:attribute name="number" type="xs:positiveInteger" use="required"/>
   </xs:complexType>
</xs:schema>

Now I need to write an XSL Stylesheet to check the same dependencies that the XML Schema does. This is because the server side uses the Schema and on the client side, a stylesheet validation is required. Not particularly sure why can not use Schema on both client/server.

Basically, I need to go through every component and find its relate-to text contents. Then I need to check to make sure this actually relates to some @number attribute in any other component but the one I am currently looking at.

I am wondering if people can help me on what the best approach is to this. Actual XSLT code is helpful but I really need to understand on how to go about it.

I am thinking of doing this

1. creating a node set of all //related-to contents and another node set of the number attribute like //@number
2. For each element in the //related-to node set, loop through the //@number and see if I find one that matches

Basically, I want to do the equivalent of this portion of my Schema



Code:
      <xs:key name="key">
         <xs:selector xpath="component"/>
         <xs:field xpath="@number"/>
      </xs:key>

      <xs:keyref name="numKey" refer="key">
         <xs:selector xpath="component/related-to"/>
         <xs:field xpath="."/>
      </xs:keyref>
Thanks
Shumba
__________________
Kind Regards,
Shumba
 
Old March 19th, 2006, 01:53 PM
mhkay's Avatar
Wrox Author
 
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
Default

First define a key that finds a component given its number:

<xsl:key name="k" match="component" use="@number"/>

Now find all the related-to elements for which there is no key match:

<xsl:variable name="unmatched" select="//related-to[not(key('k', .)]"/>

Now report errors in respect of any node in $unmatched.

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


I've only recently started studying XSLT and will need to read up on using the "key" matching. I will see if I can try to understand your advice after that. As at now, I am not sure how to fit your suggestions into my XSlT stylesheet such that I can print out anything without dependencies.
 
Old March 22nd, 2006, 03:56 PM
Authorized User
 
Join Date: Jan 2006
Posts: 14
Thanks: 0
Thanked 0 Times in 0 Posts
Default

ok. After doing some reading and practice, I think I have managed to do this.

I have first created a lookup "table" for all components based on their @number attribute key

Code:
   <xsl:key name="refNums" match="component" use="@number"/>
Then in my related-to template, I call a named template that I have written to resolve that the part actually exists in the lookup "table" above. I use the text content of related-to to find if the part really exists in the lookup "table" I created earlier. If it does not, I handle it according - I just printed out for testing purposes


Code:
   <xsl:template match="related-to">
         <xsl:call-template name="resolveNumber">
            <xsl:with-param name="partNum" select="."/>
         </xsl:call-template>
   </xsl:template>
   <xsl:template name="resolveNumber">
      <xsl:param name="partNum"/>
      <xsl:choose>

         <xsl:when test="key('refNums', $partNum)">

               Part number: <xsl:value-of select="$partNum"/> exists
         </xsl:when>
         <xsl:otherwise>

               Part number: <xsl:value-of select="$partNum"/> does not exists

         </xsl:otherwise>
      </xsl:choose>
   </xsl:template>
If there is a better way to do this, please advise

Thanks
Shumba
 
Old March 22nd, 2006, 04:45 PM
mhkay's Avatar
Wrox Author
 
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
Default

Your solution is fine. Your approach is fine too: doing some reading and experimenting and then coming back to post the solution.

Michael Kay
http://www.saxonica.com/
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference





Similar Threads
Thread Thread Starter Forum Replies Last Post
creating a subset of xml schema using XSLT kapar_p XSLT 8 November 21st, 2006 09:46 AM
Can XSLT read DTD/schema and Generate XSLT.. ROCXY XSLT 1 November 6th, 2006 09:39 AM
Access Object Dependencies apologia315 Access 0 July 31st, 2006 12:37 PM
Object Dependencies tweetweet BOOK: Access 2003 VBA Programmer's Reference 1 June 7th, 2006 01:43 PM





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