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
On 10/6/18, 9:49 AM, "Michael Kay mike(_at_)saxonica(_dot_)com"
<xsl-list-service(_at_)lists(_dot_)mulberrytech(_dot_)com> 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(_at_)contrext(_dot_)com
<xsl-list-service(_at_)lists(_dot_)mulberrytech(_dot_)com> 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>
{$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>
{$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>
{$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/calibration-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
>
>
--~----------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
EasyUnsubscribe: http://lists.mulberrytech.com/unsub/xsl-list/1167547
or by email: xsl-list-unsub(_at_)lists(_dot_)mulberrytech(_dot_)com
--~--