Re: [xsl] Re: problem with fn:contains using xsl:param

Subject: Re: [xsl] Re: problem with fn:contains using xsl:param
From: "G. Ken Holman" <gkholman@xxxxxxxxxxxxxxxxxxxx>
Date: Mon, 14 Dec 2009 22:39:08 -0500
At 2009-12-15 01:12 +0100, Piotr Dobrogost wrote:
Date: Sun, 13 Dec 2009 17:40:44 -0500
From: "G. Ken Holman"<gkholman@xxxxxxxxxxxxxxxxxxxx>
Message-Id:<7.0.1.0.2.20091213172539.025d5598@xxxxxxxxxxxxxxxxxxxxxx>

First "xsd:bool" is incomplete and would have to be "xsd:boolean".

Right.


And while it won't affect this particular example, the "protected"
way of doing what you are doing with strings is to add a space at the
start and end of your string with the tokens, and then add a space to
the start and end of the token being searched.

Right. It does effect my example as xsd:date is a substring of xsd:dateTime. How can I add a space before and after @type in
<xsl:template match="xsd:element[contains($KnownXSDTypesMap, @type)]"> statement?
I tried ' @type ' but it doesn't work. Putting, as a test, single quotes around @type like this '@type' does not work either what would suggest that @type is treated literally when quoted in such a way.

I use the pattern:


  contains(concat(' ',normalize-space($KnownXSDTypesMap),' '),
           concat(' ',normalize-space(@type),' ')

... where I can remove normalize-space() where I've been able to guarantee the string is properly formed.

In XSLT 2 you might consider something like:

    <xsl:param name="KnownXSDTypes" as="element()*">
     <type>xsd:date</type>
     <type>xsd:dateTime</type>
     <type>xsd:boolean</type>
    </xsl:param>
    ...
    <xsl:template match="xsd:element[@type=$KnownXSDTypes]">

Very nice. It solves problem from my original post.


However, I really need two things;
1. test if a value of a type attribute is on the list
2. if it's on that list I need to map it to some predefined string being used later.
Your idea solves the first problem but I still need to solve the second one. And the best solution would be to use a map to solve both problems at the same time. Do you agree?

Then I would change the above to (BTW, I changed it to a variable ... is it supposed to be parameterized from the invoking process?) the following sequence of elements which is not namespace-safe:


    <xsl:variable name="KnownXSDTypes" as="element()*">
     <mapping from="xsd:date" to="DATE"/>
     <mapping from="xsd:dateTime" to="DATETIME"/>
     <mapping from="xsd:boolean" to="BOOL"/>
    </xsl:variable>
    ...
    <xsl:template match="xsd:element[@type=$KnownXSDTypes/@from]">
      .... $KnownXSDTypes[@from=current()/@type]/@to ....

or the following temporary tree, keeping in mind what Michael pointed out regarding namespace prefixes:

  <xsl:variable name="KnownXSDTypes" as="document-node()">
    <xsl:document>
      <mapping from="xsd:date" to="DATE"/>
      <mapping from="xsd:dateTime" to="DATETIME"/>
      <mapping from="xsd:boolean" to="BOOL"/>
    </xsl:document>
  </xsl:variable>
  <xsl:key name="types" match="mapping" use="resolve-QName(@from,.)"/>

  <xsl:template match="xsd:element[key( 'types', resolve-QName(@type,.),
                                        $KnownXSDTypes )]">
    ... key( 'types', resolve-QName(@type,.), $KnownXSDTypes )/@to ...
  </xsl:template>

I made generic map template which looks like this
...
with maps looking like this

<xsl:param name="KnownXSDTypesMap">xsd:date/DATE xsd:dateTime/DATETIME xsd:boolean/BOOL</xsl:param>

That might be acceptable if you were obliged to pass the mapping as a string, but as you say that limits the characters available.


...
ps.
Yes, I saw Michael's reply but wanted to extend the scope of my original question while replying to your post.

And I saw you were willing to accept hard-wired namespace prefixes in your input XML ... I think this may be unwise ... I've noticed students of mine who have come to XSLT from XQuery prefer the prefix "xs" over "xsd" in their work. With this in mind, the approach I've used above using QNames is namespace-safe. For example, the above will work even if the input is:


  ...xmlns:xs="http://www.w3.org/2001/XMLSchema";>
  ...
  <xs:element type='xs:dateTime'>...

I hope this helps. And thanks again to Mike regarding the use of QNames.

. . . . . . . . . . . . Ken

--
XSLT/XQuery/XPath training after http://XMLPrague.cz 2010-03-15/19
Vote for your XML training:   http://www.CraneSoftwrights.com/s/i/
Crane Softwrights Ltd.          http://www.CraneSoftwrights.com/s/
Training tools: Comprehensive interactive XSLT/XPath 1.0/2.0 video
Video lesson:    http://www.youtube.com/watch?v=PrNjJCh7Ppg&fmt=18
Video overview:  http://www.youtube.com/watch?v=VTiodiij6gE&fmt=18
G. Ken Holman                 mailto:gkholman@xxxxxxxxxxxxxxxxxxxx
Male Cancer Awareness Nov'07  http://www.CraneSoftwrights.com/s/bc
Legal business disclaimers:  http://www.CraneSoftwrights.com/legal

Current Thread