Subject: Re: [xsl] constructing arrays in XSLT with templates From: "Alan Painter alan.painter@xxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> Date: Sat, 19 Jun 2021 10:30:15 -0000 |
That looks very good. I'm able to get your recommendation to work: <books> <book> <title>The C Programming Language</title> <author>Brian Kernighan</author> <author>Dennis Ritchie</author> </book> <book out-of-print="true"> <title>Principles of Compiler Design</title> <author>Alfred V. Aho</author> <author>Jeffrey D. Ullman</author> <author>J. E. Hopcrof</author> </book> </books> <?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:map="http://www.w3.org/2005/xpath-functions/map" version="3.0"> <xsl:output method="json" indent="yes" /> <xsl:template match="/" > <xsl:sequence select=" map { 'books' : array { books/book ! map:merge(( map:entry('title', title !string() ), map:entry('authors', array { author!string() } ), @out-of-print[. eq 'true'] ! map:entry('out-of-print', true()) )) } }" /> </xsl:template> </xsl:stylesheet> But I was hoping for something closer to this: map { 'books' : array { books/book ! map:merge(( map:entry('title', title !string() ), map:entry('authors', array { author!string() } ), * map:entry('out-of-print', true())[current()/@out-of-print eq 'true']* )) } } This latter one doesn't seem to work, at least not within Saxon-JS (via your excellent *xslt3fiddle* of which I am an ardent user). I'm curious why the latter doesn't work but I suspect that the context is not what I'm thinking that it is within that predicate. In any case, your generous help has been quite an eye-opener for me and has steered me in a much more expressive xpath direction. Thanks very much -alan On Sat, Jun 19, 2021 at 11:25 AM Martin Honnen martin.honnen@xxxxxx < xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> wrote: > > Am 19.06.2021 um 10:54 schrieb Alan Painter alan.painter@xxxxxxxxx: > > But I'm wondering what the equivalent would be for conditional map > > entries. > > > > > > Supposing that there is an additional optional attribute on the 'book' > > element of the original xml, 'out-of-print="true"'. > > Furthermore, let's say that the JSON maps in the 'books' array contain > > an additional field when a book is out of print. > > > > In XSLT map entries, you can write: > > > > <xsl:map> > > <xsl:map-entry key="'title'" select="title!string()" > > /> > > <xsl:map-entry key="'authors'" select="array { ./author!string() > > }" /> > > > > <xsl:if test="@out-of-print and @out-of-print eq 'true'" > > > <xsl:map-entry key="'out-of-print'" select="true()" /> > > </xsl:if> > > </xsl:map> > > > > But I'm thinking that there is not a way to express this with the 'map > > { ... }' form in xpath. > > > > map { > > 'title' : title!string(), > > 'authors' : array { author/string() }, > > ( 'out-of-print' : true() )[@out-of-print and @out-of-print eq 'true'] > > } > > > > Is there any way of doing something like this using in-line xpath? > > > My first instinct would be that the data is more consistent if you just do > > > <xsl:template match="/"> > <xsl:sequence > select="map { > 'books' : array { > books/book ! map { > 'title' : title!string(), > 'authors' : array { author/string() }, > 'out-of-print' : @out-of-print = 'true' > } > } > }"/> > </xsl:template> > > > i.e. give any map representing a book a property of the name > out-of-print with the right value. > > > Otherwise I think you can use map:merge > > > <xsl:template match="/"> > <xsl:sequence > select="map { > 'books' : array { > books/book ! > map:merge(( > map { > 'title' : title!string(), > 'authors' : array { author/string() } > }, > @out-of-print ! map:entry(local-name(), boolean(.))) > ) > } > }"/> > </xsl:template> > > > with xmlns:map="http://www.w3.org/2005/xpath-functions/map"
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] constructing arrays in XS, Martin Honnen martin | Thread | Re: [xsl] constructing arrays in XS, Martin Honnen martin |
Re: [xsl] user-defined XSLT functio, Joel Kalvesmaki dire | Date | Re: [xsl] constructing arrays in XS, Martin Honnen martin |
Month |