Subject: RE: [xsl] Very Basic Generic Filtering Question From: "M. David Peterson" <m.david@xxxxxxxxxx> Date: Thu, 10 Jun 2004 19:28:35 -0600 |
Hey Josh, You know, you're right, using a variable in a match pattern is an error. Its an error that Xalan doesn?t care about and as such is something I will use from time to time (when Xalan is the transformation engine) to solve a problem that should be fixed by changing the XML but as a consultant you don?t always have that luxury. For example, this... <?xml version="1.0"?> <foo> <a length="1"/> <b/> <c/> </foo> processed by this... <?xml version="1.0"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:variable name="foo" select="'length'"/> <xsl:output method="text"/> <xsl:template match="/"> <xsl:apply-templates select="foo/*"/> </xsl:template> <xsl:template match="a[@*[local-name() = $foo]]"> Hello World </xsl:template> </xsl:stylesheet> Outputs this when transformed by Xalan... Hello World And this when transformed by Saxon... E The match pattern in xsl:template may not contain references to variables priority.xslt file:/E:/Documents%20and%20Settings/M.David%20/My%20Documents/sample%20x slt/priority.xslt 8:1 And this when transformed by .NET XslTransform() Exception Details: System.Xml.XPath.XPathException: a[@*[local-name() = $foo]] is an invalid key pattern. It either has a variable reference or key function. Actually the error that I think you caught Josh was the fact that there was white space between the $ and the first character of the variable name. So not only am I teaching bad habits but I'm teaching them wrong as well! Sorry about that Arvind! I hope I didn?t make things worse for you! For anybody else reading this thread the above will fail in every other processor (that I know of) that isn?t Xalan. So if you choose to use the above be forewarned that it is a Xalan only solution AND it?s a hack. Thanks for catching this one Josh! Best regards, <M:D/> -----Original Message----- From: Josh Canfield [mailto:Josh.Canfield@xxxxxxxxxxxx] Sent: Thursday, June 10, 2004 6:05 PM To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx Subject: RE: [xsl] Very Basic Generic Filtering Question You can't put a variable in a template element's match attribute: Error in expression $filterElement: Unexpected token in pattern, found $ javax.xml.transform.TransformerConfigurationException: Failed to compile stylesheet. 1 error detected. This item in Dave Pawson's FAQ might help http://www.dpawson.co.uk/xsl/sect2/N7654.html#d9129e607 Josh -----Original Message----- From: M. David Peterson [mailto:m.david@xxxxxxxxxx] Sent: Thursday, June 10, 2004 4:54 PM To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx Subject: RE: [xsl] Very Basic Generic Filtering Question Hey Arvind, You're on the right track. Whenever you have an element that you want to do absolutely nothing with (and is a direct child element of the current Result Tree Fragment returned by your XPath, and therefore will be looking for somewhere to go so to speak...) all you need to do is create an empty template that matches the element name.... In this case your second template with the match attribute set to "Header". The way you would implement the same thing with your filter param would be to set the match attribute value as such... <xsl:template match="*[not(local-name() = $ filterElement)]"> ... </xsl:template> The one thing that is wrong with the below stylesheet is that you are currently running apply-templates without the select attribute and so by default it is matching all the child elements of "/" which is referred to as the root element... Which technically isn't an element that you or I ever see... but there's no need to cloud the water with why that is... In this case the only child element of root is AddressBook. In the template I assume you are matching it to you are then making a copy of the current element (AddressBook) which contains all of its children and there children etc... Which of course contains the Header element you are trying to filter out. Two ways to solve this problem... First, change the <xsl:apply-templates/> to <xsl:apply-templates select="AddressBook/*"/> to process all the children of AddressBook OR Add an <xsl:apply-templates/> to the template that AddressBook matches to as to ensure that all the children of AddressBook are recursively processed. Unless there is something specific you want to output for the element AddressBook then I would use the first method as it will save you a template or two of code, one less element to match to a template, and ultimately a faster transformation of your XML. Hope this helps! Best regards, <M:D/> -----Original Message----- From: Arvind Bassi [mailto:arvind_bassi@xxxxxxxxxxx] Sent: Thursday, June 10, 2004 4:06 PM To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx Subject: [xsl] Very Basic Generic Filtering Question I haven't done XSLT for quite some time, and its amazing how much l have forgotten. I have a very simple problem of having to filter out a specific xml element. In the example below, it is <Header>, but it should be able to be passed down as a parameter. From memory, l need to use the name function and test it against the current node, but l have tried doing this but to no avail. How can the following xml document be filtered in a generic manner? <?xml version="1.0" encoding="UTF-8"?> <AddressBook> <Header> <ElementOne id="1">hello</ElementOne> <ElementTwo id="2"> why not</ElementTwo> </Header> <People value="3"> <Name number="3"> <FirstName> Simon</FirstName> <LastName>Says</LastName> </Name> <Name number="3"> <FirstName> Simon</FirstName> <LastName>Says</LastName> </Name> <Name number="3"> <FirstName> Simon</FirstName> <LastName>Says</LastName> </Name> <Name number="3"> <FirstName> Simon</FirstName> <LastName>Says</LastName> </Name> </People> <Mary> <Had a="little"> lamb</Had> </Mary> </AddressBook> <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.1" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output indent="yes" method="xml" version="1.0"/> <xsl:param name="filterElement">Header</xsl:param> <xsl:template match="/"> <xsl:copy> <xsl:apply-templates/> </xsl:copy> </xsl:template> <xsl:template match="???????"> <xsl:copy-of select="."/> </xsl:template> <xsl:template match="????????"/> </xsl:stylesheet> Any help that can be provided would be gratefully appreciated. Thanks. Arvind. ___________________________________________________________ALL-NEW Yahoo! Messenger - sooooo many all-new ways to express yourself http://uk.messenger.yahoo.com --+------------------------------------------------------------------ XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/ or e-mail: <mailto:xsl-list-unsubscribe@xxxxxxxxxxxxxxxxxxxxxx> --+-- --+------------------------------------------------------------------ XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/ or e-mail: <mailto:xsl-list-unsubscribe@xxxxxxxxxxxxxxxxxxxxxx> --+-- --+------------------------------------------------------------------ XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/ or e-mail: <mailto:xsl-list-unsubscribe@xxxxxxxxxxxxxxxxxxxxxx> --+--
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
RE: [xsl] Very Basic Generic Filter, Josh Canfield | Thread | Building a hierarchy based on sibli, Ryan Graham |
RE: [xsl] Very Basic Generic Filter, Josh Canfield | Date | Building a hierarchy based on sibli, Ryan Graham |
Month |