![]() |
|
|
|||||||
![]() |
XML - Question on " inside function arguments |
|
|
Thread Tools | Search this Thread |
|
|
#1 |
|
Hi
I have an XML documnet and a XSLT document as shown below THe XSLT document brings back a filtered docmument that has the VendorName that starts with a particular sub-string This works as expected with alphabet and number characters and the ' (single quote ' entity) character but does not work if a double quote character " is part of the string to filter on This returns all Vendor Names that begin with A (either case) The XML Document <?xml-stylesheet type="text/xsl" href="C:\XSL1.xsl"?> <NEXXML xmlns:sql="urn:schemas-microsoft-com <columns/> <rows> <row SAPVendorRef="15001" VendorName="A" A Meats" EntityId="3021" rsposition="1"/> <row SAPVendorRef="57232" VendorName="Abbeyhouse Foods" EntityId="3050" rsposition="2"/> <row SAPVendorRef="15011" VendorName="Alexandra Rentals" EntityId="3023" rsposition="3"/> <row SAPVendorRef="10184" VendorName="Alexandra Workwear PLC" EntityId="3014" rsposition="4"/> <row SAPVendorRef="15012" VendorName="Allied Bakeries NI" EntityId="3024" rsposition="5"/> <row SAPVendorRef="60143" VendorName="Astron On Line" EntityId="3056" rsposition="6"/> <row SAPVendorRef="56531" VendorName="Backgammo'n" EntityId="3048" rsposition="7"/> <row SAPVendorRef="15062" VendorName="British Bakeries NI" EntityId="3025" rsposition="8"/> </rows> </NEXXML> The XSLT Document <xsl:stylesheet version="1.0" xmlns xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:sql="urn:schemas-microsoft-com <xsl <xsl:template match="/"> <NEXXML> <rows> <xsl:apply-templates/> </rows> </NEXXML> </xsl:template> <xsl:template match="rows"> <xsl:apply-templates select="row"/> </xsl:template> <xsl:template match="row[ starts-with(translate( @VendorName,"abcdefghijklmnopqrstuvwxyz" ,"ABCDEFGHIJKLMNOPQRS TUVWXYZ" ;,"ABCDEFGHIJKLMNOPQRSTUVWXYZ" <xsl:copy-of select="."/> </xsl:template> </xsl:stylesheet> If I want to search on the string A" the line <xsl:template match="row[ starts-with(translate( @VendorName,"abcdefghijklmnopqrstuvwxyz" ,"ABCDEFGHIJKLMNOPQRS TUVWXYZ" ;,"ABCDEFGHIJKLMNOPQRSTUVWXYZ" <xsl:copy-of select="."/> changes to: <xsl:template match="row[ starts-with(translate( @VendorName,"abcdefghijklmnopqrstuvwxyz" ,"ABCDEFGHIJKLMNOPQRS TUVWXYZ" z","ABCDEFGHIJKLMNOPQRSTUVWXYZ" <xsl:copy-of select="."/> I now get an error Expected token ')' found 'STRING' From what I can see, this is because the XML parser reads the translate function intereprets the 1st " as the start of the first argument and interprets the 2nd " as the end of the 1st argument, instead of being part of the first argument and then expects a comma (,) and the second string argument How I can make the parser take the 2nd quote as part of the first string argument if there is a quote in the 1st argument I know I could probably do this by replacing the double quotes with single quotes but then I am assumming I will get the same problem with single quotes been part of the literal string. Your help is greatly appreciated. Thanks in advance Regards David Furey David Furey |
|
|
|
|
#2 |
|
Posts: n/a
|
Hi David,
In XPath strings can be delimited by either single (&apos (" <xsl:template match="row[starts-with(translate(@VendorName,'abcdefghijklmnopqrstuv wxyz','A BCDEFGHIJKLMNOPQRSTUVWXYZ'),translate('A"','a bcdefghijklmnopqrstuvwxyz' ,'ABCDEFGHIJKLMNOPQRSTUVWXYZ'))]"> Although using a template match for this is probably quite inefficient. For two reasons... i) because you are trying to do things in a template @match you cannot use variables - which means that for every predicate [] filter evaluation you are having to uppercase the string being searched for (i.e. that second translate() call on 'A"'). ii) also, because the filtering is being done at the template match, you are sending out nodes that you are uninterested in - which are being caught by the XSLT built-in rule templates (which may mean that if at some point in the future your <row> elements have any text node children you may end up with unexpected text in the output). I assume at some point you are going to parameterize the search - at which point using template matches for the filtering will become impossible. You might want to try something like... <xsl:stylesheet version="1.0" xmlns xmlns:sql="urn:schemas-microsoft-com <xsl <xsl <!-- convert the param to upper case just once --> <xsl:variable name="uc-search-for" select="translate($search-for,'abcdefghijklmnopqrstuvwxyz','ABCDEFGHIJKLMNOP QRSTUVWXYZ')"/> <xsl:template match="/"> <NEXXML> <rows> <xsl:apply-templates/> </rows> </NEXXML> </xsl:template> <xsl:template match="rows"> <xsl:apply-templates select="row[starts-with(translate(@VendorName,'abcdefghijklmnopqrstuv wxyz',' ABCDEFGHIJKLMNOPQRSTUVWXYZ'),$uc-search-for)]"/> </xsl:template> <xsl:template match="row"> <xsl:copy-of select="."/> </xsl:template> </xsl:stylesheet> Which, apart from making the code dynamic, will perform about twice as fast as your original fixed stylesheet. Hope this helps Marrow http://www.marrowsoft.com - home of Xselerator (XSLT IDE and debugger) http://www.topxml.com/Xselerator "David Furey" <> wrote in message news:bdabpt$i7m$... > Hi > > I have an XML documnet and a XSLT document as shown below > > THe XSLT document brings back a filtered docmument that has the VendorName > that starts with a particular sub-string > This works as expected with alphabet and number characters and the ' (single > quote ' entity) character but does not work if a double quote character > " is part of the string to filter on > This returns all Vendor Names that begin with A (either case) > > The XML Document > > <?xml-stylesheet type="text/xsl" href="C:\XSL1.xsl"?> > <NEXXML xmlns:sql="urn:schemas-microsoft-com > <columns/> > <rows> > <row SAPVendorRef="15001" VendorName="A" A Meats" EntityId="3021" > rsposition="1"/> > <row SAPVendorRef="57232" VendorName="Abbeyhouse Foods" EntityId="3050" > rsposition="2"/> > <row SAPVendorRef="15011" VendorName="Alexandra Rentals" EntityId="3023" > rsposition="3"/> > <row SAPVendorRef="10184" VendorName="Alexandra Workwear PLC" > EntityId="3014" rsposition="4"/> > <row SAPVendorRef="15012" VendorName="Allied Bakeries NI" EntityId="3024" > rsposition="5"/> > <row SAPVendorRef="60143" VendorName="Astron On Line" EntityId="3056" > rsposition="6"/> > <row SAPVendorRef="56531" VendorName="Backgammo'n" EntityId="3048" > rsposition="7"/> > <row SAPVendorRef="15062" VendorName="British Bakeries NI" EntityId="3025" > rsposition="8"/> > </rows> > </NEXXML> > > The XSLT Document > > <xsl:stylesheet version="1.0" > xmlns > xmlns:fo="http://www.w3.org/1999/XSL/Format" > xmlns:sql="urn:schemas-microsoft-com > <xsl > <xsl:template match="/"> > <NEXXML> > <rows> > <xsl:apply-templates/> > </rows> > </NEXXML> > </xsl:template> > <xsl:template match="rows"> > <xsl:apply-templates select="row"/> > </xsl:template> > <xsl:template match="row[ starts-with(translate( > @VendorName,"abcdefghijklmnopqrstuvwxyz" ,"ABCDEFGHIJKLMNOPQRS > TUVWXYZ" > ;,"ABCDEFGHIJKLMNOPQRSTUVWXYZ" > <xsl:copy-of select="."/> > </xsl:template> > </xsl:stylesheet> > > If I want to search on the string A" the line > > <xsl:template match="row[ starts-with(translate( > @VendorName,"abcdefghijklmnopqrstuvwxyz" ,"ABCDEFGHIJKLMNOPQRS > TUVWXYZ" > ;,"ABCDEFGHIJKLMNOPQRSTUVWXYZ" > <xsl:copy-of select="."/> > > changes to: > > <xsl:template match="row[ starts-with(translate( > @VendorName,"abcdefghijklmnopqrstuvwxyz" ,"ABCDEFGHIJKLMNOPQRS > TUVWXYZ" > z","ABCDEFGHIJKLMNOPQRSTUVWXYZ" > <xsl:copy-of select="."/> > > I now get an error Expected token ')' found 'STRING' > > From what I can see, this is because the XML parser reads the translate > function intereprets the 1st " as the start of the first argument and > interprets the 2nd " as the end of the 1st argument, instead of being > part of the first argument and then expects a comma (,) and the second > string argument > > How I can make the parser take the 2nd quote as part of the first string > argument if there is a quote in the 1st argument > I know I could probably do this by replacing the double quotes with single > quotes but then I am assumming I will get the same problem with single > quotes been part of the literal string. > > Your help is greatly appreciated. Thanks in advance > > Regards David Furey > > > |
|