Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   XML (http://www.velocityreviews.com/forums/f32-xml.html)
-   -   Question on " inside function arguments (http://www.velocityreviews.com/forums/t164945-question-on-inside-function-arguments.html)

David Furey 06-24-2003 08:19 PM

Question on " inside function arguments
 
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:output 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;abcde fghijklmnopqrstuvwxyz&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;abcde fghijklmnopqrstuvwxyz&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 06-25-2003 08:50 AM

Re: Question on &quot; inside function arguments
 
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,'abcdefghijklmnopqrstuv wxyz','A
BCDEFGHIJKLMNOPQRSTUVWXYZ'),translate('A&quot;','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&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:output 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,'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" <dave@furey.fsnet.co.uk> wrote in message
news:bdabpt$i7m$1@news7.svr.pol.co.uk...
> 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:output 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;abcde fghijklmnopqrstuvwxyz&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;abcde fghijklmnopqrstuvwxyz&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
>
>
>





All times are GMT. The time now is 04:56 AM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.