#415 FastStringBuilder and Maps

v8.5.1
closed
Michael Kay
5
2012-10-08
2005-11-02
Rob
No

I am doing odd things with a map inside an xslt page
where at the top of the page:

...
xmlns:map="java:java.util.TreeMap" (or HashMap I've
tried both)
...
<xsl:variable name="mymap" select="map:new()"/>
...

<xsl:value-of select="map:put($mymap,$keyname,concat($listenerOutput,''))"/>

where keyname is something like 'html.center'

when I query the map to see what the keySet is
<xsl:value-of select="map:keySet($mymap)"/>
all looks well; however it is not possible to retrieve
the data using a key no matter what I do. for example:

<xsl:value-of select="map:get($mymap,'html.center')"/>
returns nothing

and
<xsl:value-of select="map:containsKey($mymap, 'html.center')"/>
returns false

but listing the keySet
<xsl:value-of select="map:keySet($mymap)"/>
says that html.center is indeed there. I am just taking
a wild guess - does FastStringBuffer need a compare
method? I think it might be that the map can't find the
key because of that (seeing FastStringBuffer is not a
subclass of string)

I've tried string() and concat() to try to make they
key a "for sure" string, but that's not working either.

This process used to work pre 8 (or early 8 I am not
100% sure but it did work at one point).

Thank you for all your hard work and your killer
transformer btw

Discussion

  • Michael Kay
    Michael Kay
    2005-11-02

    Logged In: YES
    user_id=251681

    I can't reproduce this. This stylesheet:

    <xsl:stylesheet version="1.0"

    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

    <xsl:param name="keyname" select="'html.center'"/>
    <xsl:param name="listenerOutput" select="'abracadabra'"/>

    <xsl:template name="main" xmlns:map="java:java.util.TreeMap">
    <xsl:variable name="mymap" select="map:new()"/>

    <put><xsl:value-of select="map:put($mymap,$keyname,concat($listenerOutput,''))"/></put>

    <keySet><xsl:value-of select="map:keySet($mymap)"/></keySet>

    <keyValue><xsl:value-of select="map:get($mymap,'html.center')"/></keyValue>

    <contains><xsl:value-of select="map:containsKey($mymap,'html.center')"/></contains>
    </xsl:template>

    </xsl:stylesheet>

    produces this output:

    <put xmlns:map="java:java.util.TreeMap"/> <keySet xmlns:map="java:java.util.TreeMap">[html.center]</keySet> <keyValue xmlns:map="java:java.util.TreeMap">abracadabra</keyValue> <contains xmlns:map="java:java.util.TreeMap">true</contains>

    Please submit a complete self-contained test case that
    demonstrates the problem, and say which version you are running.

     
  • Michael Kay
    Michael Kay
    2005-11-02

    Logged In: YES
    user_id=251681

    Another observation: the value actually stored in your Map
    is a Java object of class net.sf.saxon.value.StringValue.
    Because the signature of the put() and get() methods
    requires only Object, it's important that the values you
    supply in your calls to these methods are actually of the
    same XPath type. StringValue has an equals() method which
    relies on String.equals(). It should also cause a string to
    match an UntypedAtomicValue. But if you supplied a node in
    the call on get() it wouldn't work: as the Java method
    accepts Object, the node would not be atomized.

    I don't think the behaviour of FastStringBuffer comes into it.

     
  • Rob
    Rob
    2005-11-02

     
    Attachments
  • Rob
    Rob
    2005-11-02

    Logged In: YES
    user_id=570959

    I am not sure if it will help, but here is the file - it's part of a larger
    system though...

    the map key get set at line 140 and retrived at 174. The template
    "thoth:include" runs another java extention that does another transform
    and returns the result as a java String, looks something like:

    <xsl:variable name="results" select="xslexe:transform( xslexe:new(), concat($request_string,''), concat($page_string,''), thoth:variableToList($params,'`'), concat('/',$file) )"/>

        <xsl:value-of select="$results" />
    

    where that method returns a proper java String.

    And it was an eariler version of saxon 8 that it worked (the name of the
    working jar is saxon8.jar, and the date on the file is May 30th)

     
  • Michael Kay
    Michael Kay
    2005-11-02

    Logged In: YES
    user_id=251681

    Sorry, I can't really help you debug this unless you provide
    me with something I can run.

    My guess would be that you're falling foul of some
    optimization. Calling methods with side-effects (such as
    map.put()) can behave in very unpredictable ways, given the
    non-sequential execution model of XSLT. It's really not a
    recommended way of using the language.

    I'd suggest you write your own Map class as a wrapper around
    the Hashmap class, and trace the calls on put and get, with
    particular attention to the types of the objects that are
    being put/got.

    Michael Kay

     
  • Michael Kay
    Michael Kay
    2005-11-02

    Logged In: YES
    user_id=251681

    By the way, I should have reminded you of the notice on the
    "Submit" bug" form that this section of the site is for
    comfirmed bugs only. Please use "support requests" or the
    saxon-help list/forum in future. To make life easier for
    people searching for real bugs, I'm marking this one as
    "closed/invalid".

    Michael Kay

     
  • Rob
    Rob
    2005-11-02

    Logged In: YES
    user_id=570959

    I fully understand - I was assuming it was a bug in saxon since it worked
    with an earily version and not with the lastest. I'll write a standlone test
    case as you suggested later today.