Subject: Re: [xsl] Defining variables as sequence of strings From: "Dimitre Novatchev dnovatchev@xxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> Date: Fri, 15 May 2015 03:40:58 -0000 |
>> <xsl:variable name="vSorted" as="xs:string*"> >> <xsl:perform-sort select="distinct-values($vTypes)"> >> <xsl:sort select="."/> >> </xsl:perform-sort> >> </xsl:variable> >> >> <xsl:value-of select= >> "$vSorted/concat('...Some other text (', ., ') More Text....')" >> separator="
"/> > > OK, looking at this, I don't think the / operator is allowed on a > sequence of strings -- it is allowed only on a sequence of nodes. > > However I used XML-SPY -- the only XSLT 2.0 processor I have at work, > and it worked OK. > > > I will need to get back home and try using Saxon. Hi Joseph, Yes, you are right that it is close to impossible in XSLT 2.0 to process a sequence of atomic items (strings in this case) in a polymorphic way. Here is one solution that avoids using <xsl:for-each> or using recursively called named templates: <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text"/> <xsl:key name="kTextByVal" match="t" use="."/> <xsl:template match="/*"> <xsl:variable name="vTypes"> <xsl:apply-templates select="*/@type"/> </xsl:variable> <xsl:apply-templates mode="distinct-text" select= "$vTypes/*[generate-id() =generate-id(key('kTextByVal', ., $vTypes)[1])]"> <xsl:sort/> </xsl:apply-templates> </xsl:template> <xsl:template match="text()" mode="distinct-text"> ...Some other text (<xsl:value-of select="."/>) More Text....) </xsl:template> <xsl:template match="property/@type[. eq 'foo']"> <t>c</t> <t>d</t> </xsl:template> <xsl:template match="property/@type[. = ('bar', 'baz', 'bof')]"> <t>b</t> <t>c</t> </xsl:template> <xsl:template match="property/@type" priority="-1"> <t>a</t> <t>b</t> </xsl:template> </xsl:stylesheet> When this transformation is applied on the previously supplied XML document: <object> <property name="name" type="foo"/> <property name="key" type="bar"/> <property name="size" type="baz"/> <property name="age" type="bof"/> <property name="grade" type="goo"/> </object> the wanted result is produced: ...Some other text (a) More Text....) ...Some other text (b) More Text....) ...Some other text (c) More Text....) ...Some other text (d) More Text....) You can certainly spot that I cheated, and the intermediate results are not just sequences of strings, but sets of elements, whose text-node children have as value the wanted strings. And also, I am not using the distinct-values() function, but Muenchiam grouping (<xsl:for-each-group> can also be used) to avoid getting as result a sequence of strings. This allows us to apply templates on the elements and to use an <xsl:sort/> child of the <xsl:apply-templates> instruction, to perform the sorting. In contrast, see how easy is to do the same in XSLT 3.0: <xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xsl:output method="text"/> <xsl:template match="/*"> <xsl:variable name="vTypes" as="xs:string*"> <xsl:apply-templates select="*/@type"/> </xsl:variable> <xsl:apply-templates select="distinct-values($vTypes)"> <xsl:sort/> </xsl:apply-templates> </xsl:template> <xsl:template match=".[. instance of xs:string]"> ...Some other text (<xsl:value-of select="."/>) More Text....') </xsl:template> <xsl:template match="property/@type[. eq 'foo']"> <xsl:sequence select="'c', 'd'"/> </xsl:template> <xsl:template match="property/@type[. = ('bar', 'baz', 'bof')]"> <xsl:sequence select="'b', 'c'"/> </xsl:template> <xsl:template match="property/@type" priority="-1"> <xsl:sequence select="'b', 'a'"/> </xsl:template> </xsl:stylesheet> Here we really apply templates on a the sequence of strings: <xsl:apply-templates select="distinct-values($vTypes)"> <xsl:sort/> </xsl:apply-templates> and the processing is done in the template: <xsl:template match=".[. instance of xs:string]"> ...Some other text (<xsl:value-of select="."/>) More Text....') </xsl:template> which matches any string. This is a powerful new feature of XSLT 3.0, among many other amazing features. -- Cheers, Dimitre Novatchev --------------------------------------- Truly great madness cannot be achieved without significant intelligence. --------------------------------------- To invent, you need a good imagination and a pile of junk ------------------------------------- Never fight an inanimate object ------------------------------------- To avoid situations in which you might make mistakes may be the biggest mistake of all ------------------------------------ Quality means doing it right when no one is looking. ------------------------------------- You've achieved success in your field when you don't know whether what you're doing is work or play ------------------------------------- To achieve the impossible dream, try going to sleep. ------------------------------------- Facts do not cease to exist because they are ignored. ------------------------------------- Typing monkeys will write all Shakespeare's works in 200yrs.Will they write all patents, too? :) ------------------------------------- I finally figured out the only reason to be alive is to enjoy it.
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] Defining variables as seq, Dimitre Novatchev dn | Thread | Re: [xsl] Defining variables as seq, Wendell Piez wapiez@ |
Re: [xsl] Defining variables as seq, Dimitre Novatchev dn | Date | Re: [xsl] Defining variables as seq, Wendell Piez wapiez@ |
Month |