Question on " inside function arguments

Discussion in 'XML' started by David Furey, Jun 24, 2003.

  1. David Furey

    David Furey Guest

    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:xml-sql">
    <columns/>
    <rows>
    <row SAPVendorRef="15001" VendorName="A&quot; 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:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:fo="http://www.w3.org/1999/XSL/Format"
    xmlns:sql="urn:schemas-microsoft-com:xml-sql">
    <xsl:eek:utput method="xml"/>
    <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,&quot;abcdefghijklmnopqrstuvwxyz&quot;,&quot;ABCDEFGHIJKLMNOPQRS
    TUVWXYZ&quot;),translate(&quot;A&quot;,&quot;abcdefghijklmnopqrstuvwxyz&quot
    ;,&quot;ABCDEFGHIJKLMNOPQRSTUVWXYZ&quot;)) ]">
    <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,&quot;abcdefghijklmnopqrstuvwxyz&quot;,&quot;ABCDEFGHIJKLMNOPQRS
    TUVWXYZ&quot;),translate(&quot;A&quot;,&quot;abcdefghijklmnopqrstuvwxyz&quot
    ;,&quot;ABCDEFGHIJKLMNOPQRSTUVWXYZ&quot;)) ]">
    <xsl:copy-of select="."/>

    changes to:

    <xsl:template match="row[ starts-with(translate(
    @VendorName,&quot;abcdefghijklmnopqrstuvwxyz&quot;,&quot;ABCDEFGHIJKLMNOPQRS
    TUVWXYZ&quot;),translate(&quot;A&quot;&quot;,&quot;abcdefghijklmnopqrstuvwxy
    z&quot;,&quot;ABCDEFGHIJKLMNOPQRSTUVWXYZ&quot;)) ]">
    <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 &quot; as the start of the first argument and
    interprets the 2nd &quot; 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, Jun 24, 2003
    #1
    1. Advertising

  2. David Furey

    Marrow Guest

    Hi David,

    In XPath strings can be delimited by either single (&apos;) or double
    (&quot;) marks. So your template could read...

    <xsl:template
    match="row[starts-with(translate(@VendorName,'abcdefghijklmnopqrstuvwxyz','A
    BCDEFGHIJKLMNOPQRSTUVWXYZ'),translate('A&quot;','abcdefghijklmnopqrstuvwxyz'
    ,'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&quot;').
    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:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:sql="urn:schemas-microsoft-com:xml-sql">
    <xsl:eek:utput method="xml"/>
    <xsl:param name="search-for" select="'a&quot;'"/>
    <!-- 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,'abcdefghijklmnopqrstuvwxyz','
    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 &apos; 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:xml-sql">
    > <columns/>
    > <rows>
    > <row SAPVendorRef="15001" VendorName="A&quot; 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:xsl="http://www.w3.org/1999/XSL/Transform"
    > xmlns:fo="http://www.w3.org/1999/XSL/Format"
    > xmlns:sql="urn:schemas-microsoft-com:xml-sql">
    > <xsl:eek:utput method="xml"/>
    > <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,&quot;abcdefghijklmnopqrstuvwxyz&quot;,&quot;ABCDEFGHIJKLMNOPQRS
    >

    TUVWXYZ&quot;),translate(&quot;A&quot;,&quot;abcdefghijklmnopqrstuvwxyz&quot
    > ;,&quot;ABCDEFGHIJKLMNOPQRSTUVWXYZ&quot;)) ]">
    > <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,&quot;abcdefghijklmnopqrstuvwxyz&quot;,&quot;ABCDEFGHIJKLMNOPQRS
    >

    TUVWXYZ&quot;),translate(&quot;A&quot;,&quot;abcdefghijklmnopqrstuvwxyz&quot
    > ;,&quot;ABCDEFGHIJKLMNOPQRSTUVWXYZ&quot;)) ]">
    > <xsl:copy-of select="."/>
    >
    > changes to:
    >
    > <xsl:template match="row[ starts-with(translate(
    >

    @VendorName,&quot;abcdefghijklmnopqrstuvwxyz&quot;,&quot;ABCDEFGHIJKLMNOPQRS
    >

    TUVWXYZ&quot;),translate(&quot;A&quot;&quot;,&quot;abcdefghijklmnopqrstuvwxy
    > z&quot;,&quot;ABCDEFGHIJKLMNOPQRSTUVWXYZ&quot;)) ]">
    > <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 &quot; as the start of the first argument and
    > interprets the 2nd &quot; 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
    >
    >
    >
     
    Marrow, Jun 25, 2003
    #2
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Phil Winstanley [Microsoft MVP ASP.NET]

    Re: validateRequest=&quot;false&quot; not working in web.config or page directive

    Phil Winstanley [Microsoft MVP ASP.NET], May 16, 2004, in forum: ASP .Net
    Replies:
    0
    Views:
    645
    Phil Winstanley [Microsoft MVP ASP.NET]
    May 16, 2004
  2. usr2003
    Replies:
    4
    Views:
    594
    usr2003
    Sep 19, 2003
  3. Frank Schmitt
    Replies:
    0
    Views:
    494
    Frank Schmitt
    Oct 14, 2003
  4. Ahti Legonkov
    Replies:
    0
    Views:
    508
    Ahti Legonkov
    Dec 12, 2003
  5. jmborr
    Replies:
    1
    Views:
    423
    Stargaming
    Nov 3, 2007
Loading...

Share This Page