[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message] Re: Comparing attribute values with the matches() fun
Tony Cusack wrote: Hi > For example I want to run a test at the beginning of each > execution of the stylesheet to check that the above > mentioned business rule has been observed. I am not sure, but I think you want to check that there is no @audience that contains a letter that its first @audience that appears on an ancestor doesn't contain. If it's the case, I'd use instead string-to-codepoints(), and set comparison operators to see if there is an error. If you only want to do a check at the beginning of your stylesheet, I'd use a recursive template in a specific mode that pass the letters down. If you want to be able to get all the descendent @audience that have an error, I would instead use an appropriate predicate. The later is maybe simpler, but a naive implementation will evaluate string-to-codepoints() several times for the parents, while it is evaluated only once for each @audience with the former. But I didn't do any performance test. The following stylesheet shows how to do both ways. I don't think that's possible to write a single XPath expression without the help of a function to introduce at least one variable. Maybe someone else? <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:my="tcusack.xsl" version="2.0"> <xsl:output method="text"/> <!-- launch both ways --> <xsl:template match="/"> <xsl:apply-templates mode="check"/> <xsl:text>-- </xsl:text> <xsl:value-of separator=" " select=" Publication//*/@audience[my:error-p(.)]/../@title"/> <xsl:text>-- </xsl:text> <!-- add main processing... --> </xsl:template> <!-- #1 the predicate --> <xsl:function name="my:error-p" as="xs:boolean"> <xsl:param name="a" as="attribute(audience)"/> <xsl:variable name="letters" select="string-to-codepoints($a)"/> <xsl:variable name="parent" select=" ($a/../ancestor::*/@audience)[1]/string-to-codepoints(.)"/> <xsl:sequence select="exists($letters[not(. = $parent)])"/> </xsl:function> <!-- #2 ignore text nodes while checking --> <xsl:template match="text()" mode="check"/> <!-- #2 the initial codepoints set --> <xsl:template match="Publication" priority="1" mode="check"> <xsl:apply-templates mode="check"> <xsl:with-param name="letters" select=" string-to-codepoints(@audience)"/> </xsl:apply-templates> </xsl:template> <!-- #2 when there is no @audience, just pass the set as it is --> <xsl:template match="*[empty(@audience)]" mode="check"> <xsl:param name="letters" as="xs:integer+"/> <xsl:apply-templates mode="check"> <xsl:with-param name="letters" select="$letters"/> </xsl:apply-templates> </xsl:template> <!-- #2 compare the @audience letters to the first ancestor's @audience, then pass the current letters down --> <xsl:template match="*[exists(@audience)]" mode="check"> <xsl:param name="letters" as="xs:integer+"/> <xsl:variable name="new" as="xs:integer+" select=" string-to-codepoints(@audience)"/> <xsl:if test="exists($new[not(. = $letters)])"> <xsl:value-of select="@title"/> <xsl:text> </xsl:text> </xsl:if> <xsl:apply-templates mode="check"> <xsl:with-param name="letters" select="$new"/> </xsl:apply-templates> </xsl:template> </xsl:stylesheet> Regards, --drkm _____________________________________________________________________________ Envoyez avec Yahoo! Mail. Une boite mail plus intelligente http://mail.yahoo.fr
|
PURCHASE STYLUS STUDIO ONLINE TODAY!Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced! Download The World's Best XML IDE!Accelerate XML development with our award-winning XML IDE - Download a free trial today! Subscribe in XML format
|