Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

XSLT : Creating a Map in XSLT

Tags:

I want to have a key value map in xsl and so defined a variable which has an xml fragment, but later when I try to access the xml nodes in the variable I get an error that type of the xpath xpression cannot be resolved.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">     <xsl:template match="/">         <xsl:variable name="map">             <map>                 <entry key="key-1">value1</entry>                 <entry key="key-2">value2</entry>                 <entry key="key-3">value3</entry>             </map>         </xsl:variable>         <output>             <xsl:value-of select="$map/entry[@key='key-1']"/>         </output>     </xsl:template> </xsl:stylesheet> 
like image 871
keshav84 Avatar asked Sep 02 '10 10:09

keshav84


People also ask

What is XSLT mapping?

Use. Interface descriptions are in the form of XML documents. XSL Transformation (XSLT) is a member of the XML family of languages. It describes how one XML structure is transformed into another XML structure.

Can we use XQuery in XSLT?

You can call any of the MarkLogic Server Built-In XQuery functions from an XSLT stylesheet.

What is the difference between XSLT and xsl?

XSL Transformation (XSLT)XSLT is designed to be used as part of XSL. In addition to XSLT, XSL includes an XML vocabulary for specifying formatting. XSL specifies the styling of an XML document by using XSLT to describe how the document is transformed into another XML document that uses the formatting vocabulary.


2 Answers

XSLT 2.0

Using XSLT 2.0, the following solution works:

  <xsl:variable name="map">     <entry key="key-1">value1</entry>     <entry key="key-2">value2</entry>     <entry key="key-3">value3</entry>   </xsl:variable>    <xsl:template match="/">     <output>       <xsl:value-of select="$map/entry[@key='key-1']"/>     </output>   </xsl:template> 

XSLT 1.0

You cannot use a result tree fragment in a XPath expression in XSLT 1.0, but fn:document() can retrieve map values. An answer to a similar question will work here:.

<xsl:value-of select="document('')//xsl:variable[@name='map']/map/entry[@key='key-1']"/> 

As described in the XSLT 1.0 specification:

document('') refers to the root node of the stylesheet; the tree representation of the stylesheet is exactly the same as if the XML document containing the stylesheet was the initial source document.

However, you don't need to use xsl:variable for this. You could specify your map node directly under xsl:stylesheet, but you must remember that a top level elements must have a non null namespace URI:

<xsl:stylesheet    version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"    xmlns:my="some.uri" exclude-result-prefixes="my">    <my:map>     <entry key="key-1">value1</entry>     <entry key="key-2">value2</entry>     <entry key="key-3">value3</entry>   </my:map>    <xsl:template match="/">     <output>       <xsl:value-of select="document('')/*/my:map/entry[@key='key-1']"/>     </output>   </xsl:template> </xsl:stylesheet> 
like image 107
Per T Avatar answered Oct 09 '22 10:10

Per T


You can sort of work around XSLT 1.0 missing support for using the variable's contents as a node set. You'll have to rely on extensions added by the parser's maker. For example, Microsoft has offered a function to work around this: node-set()

Your XSL will look like this:

<xsl:stylesheet version="1.0"                  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"                 xmlns:msxsl="urn:schemas-microsoft-com:xslt">     <xsl:template match="/">         <xsl:variable name="map">             <map>                 <entry key="key-1">value1</entry>                 <entry key="key-2">value2</entry>                 <entry key="key-3">value3</entry>             </map>         </xsl:variable>         <output>             <xsl:value-of select="msxsl:node-set($map)/map/entry[@key='key-1']"/>         </output>     </xsl:template> </xsl:stylesheet> 

Notice the namespace and the msxsl-prefix here. This will only work in applications based on Microsoft's parser (for example: Internet Explorer utilizes it, as well as .NET). Other parsers may or may not have such an extension (Saxxon does, for example, but it's named a bit differently). But, it eliminates depending on XSLT 2.0, as this will work fine in XSLT 1.0 and Microsoft has yet to support XSLT 2.0 in their XML library (unless they've added it recently).

Depending on the parser you're using, the above may work fine for you, otherwise Per T's answer is better for you.

like image 23
Rob Avatar answered Oct 09 '22 10:10

Rob