[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Re: Better "Report Map" Function?

Subject: Re: Better "Report Map" Function?
From: "Eliot Kimber ekimber@xxxxxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Sat, 6 Oct 2018 15:24:26 -0000
Re:  Better "Report Map" Function?
Now that I look at my code again I think the lack of return type was in
intentional in that I was trying to have both the overall map data shown as
well as get the Saxon element serialization when outside of a "value-of"
context. But now I realize that the way I've used it is usually in
"{local:report-map($map)}", which of course undoes that. Hmph. But setting the
return type to xs:string without doing more with element() values would be
bad.

Cheers,

E.

--
Eliot Kimber
http://contrext.com


o;?On 10/6/18, 10:10 AM, "Eliot Kimber ekimber@xxxxxxxxxxxx"
<xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> wrote:

    You're right, I failed to set a return type (which I would normally always
do). The intent is definitely to return a string.

    I haven't tried to make it 100% general at this point since this was
something I hacked quickly in the context of debugging other code.

    I will correct the key sorting--I knew assuming the keys were strings was
not sufficient but all the maps in my current projects only use string keys.

    For handling the possible entry values, I was pretty much just adding
handlers as I needed them. For example, using this on the result of Saxon's
collection() extensions that return maps of file information made it clear
that I needed an "other" category...

    Cheers,

    Eliot

    --
    Eliot Kimber
    http://contrext.com


    o;?On 10/6/18, 9:49 AM, "Michael Kay mike@xxxxxxxxxxxx"
<xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> wrote:

        I wonder if this is really what you want?

        You haven't declared a return type for the function, so there's going
to be no conversion applied, which means it's going to output a sequence of
interspersed text and element nodes. That's probably fine if the function call
always appears within xsl:value-of, but it's not very convenient if, for
example, you want to call it as an argument of contains() or substring(). I
would have thought a function that returned a string would be more useful.

        And a function that only handles map values that are maps, elements,
document nodes, single strings, single booleans, or single integers doesn't
feel very general-purpose.

        But you're right that there's probably nothing off-the-shelf that
gives you exactly what you want. For many purposes (e.g. diagnostic output)
the serialize() function with method=adaptive will be adequate, but if you
want something better then you have to do it yourself.

        Incidentally, sorting the keys of a map like this will fail if the
keys include non-ordered values such as QNames, of if they include a mixture
of strings and numbers. If you want to be sure the sort won't fail, convert
keys to strings before sorting.

        Michael Kay
        Saxonica

        > On 6 Oct 2018, at 14:33, Eliot Kimber ekimber@xxxxxxxxxxxx
<xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> wrote:
        >
        > I needed a way to report the contents of maps as nicely-formatted
strings using XSLT 3 and Saxon (Saxon's built-in serialization of maps did not
really satisfy me).
        >
        > Here's my solution:
        >
        >  <xsl:function name="local:report-map">
        >    <xsl:param name="map" as="map(*)"/>
        >    <xsl:param name="level" as="xs:integer"/>
        >
        >    <xsl:variable name="indent" as="xs:string?"
        >      select="(for $i in 1 to $level return '  ') => string-join()"
        >    />
        >    <xsl:text>&#x0a;{$indent}{{</xsl:text>
        >    <xsl:for-each select="map:keys($map) => sort()">
        >      <xsl:variable name="key" select="."/>
        >      <xsl:variable name="value" select="map:get($map, $key)"/>
        >      <xsl:text>&#x0a;{$indent}  "{$key}" : </xsl:text>
        >      <xsl:choose>
        >        <xsl:when test="$value instance of map(*)">
        >          <xsl:text> Map:</xsl:text>
        >          <xsl:sequence select="local:report-map($value, $level +
3)"/>
        >        </xsl:when>
        >        <xsl:when test="$value instance of element()">
        >          <xsl:sequence select="$value"/>
        >        </xsl:when>
        >        <xsl:when test="$value instance of document-node()">
        >          <xsl:text> document-node(): {name($value/*)} -
"{document-uri($value)}"</xsl:text>
        >        </xsl:when>
        >        <xsl:when test="$value instance of xs:string or $value
instance of xs:boolean or $value instance of xs:integer">
        >          <xsl:text>"{$value}"</xsl:text>
        >        </xsl:when>
        >        <xsl:otherwise>
        >          <xsl:text>unhandled value</xsl:text>
        >        </xsl:otherwise>
        >      </xsl:choose>
        >    </xsl:for-each>
        >    <xsl:text>&#x0a;{$indent}}}</xsl:text>
        >  </xsl:function>
        >
        > Which produces output like this:
        >
        > {
        >   "baseType" : "map"
        >   "doc" :  document-node(): map -
"file:/Users/ekimber/workspace/paccar/repo/paccar/sample_data/test-project/ca
libration-data/MX11_NA/calibrationSLMP_MX11_NA.ditamap"
        >   "engineFamilies" : "10.8M01"
        >   "key" : ""
        >   "relpath" :
"calibration-data/MX11_NA/calibrationSLMP_MX11_NA.ditamap"
        >   "type" : "map"
        > }
        >
        > I'm happy with the result but wondering if there's not a more
efficient/cleaner/more elegant way to do the same thing?
        >
        > Cheers,
        >
        > E.
        > --
        > Eliot Kimber
        > http://contrext.com

Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.