www.webdeveloper.com
Results 1 to 7 of 7

Thread: XSL,XPath: How to use xpath expression in source xml

Hybrid View

  1. #1
    Join Date
    Aug 2007
    Posts
    4

    XSL,XPath: How to use xpath expression in source xml

    I would like to ask for help. For example my xml source has some attribute node whose value is an xpath expression. How would I use that value as an xpath expression in my xsl?

    e.g.

    <tag attr=/tag2/somechild/>
    <tag2><somechild>value</somechild></tag2>
    <tag3><somechild2>value2</somechild2></tag3>

    In my case, the value of the attribute "attr" is dynamic (changing), and I want my xsl file to access the value according to the value of "attr" (an xpath expression). How can I do this? That is, how can I write the xpath expression that would select the value that the value of the "attr" points to?

    In essence, I would like to have something like:
    <xsl:for-each select="the xpath expression in the value of attr">, and
    <xsl:value-of select="the xpath expression in the value of attr">
    but how can I do this?

    Thank you very much!

  2. #2
    Join Date
    May 2007
    Posts
    288
    exslt
    http://www.exslt.org/dyn/functions/evaluate/

    If you are able to call an external function, you could use either javascript's or .Net's SelectNodes property. eg http://www.thescripts.com/forum/thread177329.html

  3. #3
    Join Date
    Aug 2007
    Posts
    4
    Thanks! I'll try.

    Are there other ways, especially those that are innate in xsl. That is, anything that does not call external functions?

    Thanks in advance.

  4. #4
    Join Date
    May 2007
    Posts
    288
    If you have a really simple path, it's possible to do the value-of purely in XSLT. Basically, it's a recursive template, that holds 2 variables.
    1. Current Context position.
    2. Current String.
    Can't currently find the code for it, but am looking.

    For-each is harder, and would probably require the use of either multiple templates and/or a node-set extension function.

  5. #5
    Join Date
    May 2007
    Posts
    288
    Code:
    <xsl:template name="evaluate">
    	<xsl:param name="xpath"/>
    	<xsl:choose>
    		<xsl:when test="$xpath=''">
    			<xsl:value-of select="."/>
    		</xsl:when>
    		<xsl:when test="contains($xpath, '//')">
    			<xsl:variable name="temp" select="substring-after($xpath,'//')"/>
    			<xsl:variable name="searchNode">
    				<xsl:choose>
    					<xsl:when test="contains($temp, '/')">
    						<xsl:value-of select="substring-before($temp, '/')"/>
    					</xsl:when>
    					<xsl:otherwise>
    						<xsl:value-of select="$temp"/>
    					</xsl:otherwise>
    				</xsl:choose>
    			</xsl:variable>
    			<xsl:for-each select="//*[name() = $searchNode]">
    				<xsl:call-template name="evaluate">
    					<xsl:with-param name="xpath" select="substring(substring-after($temp, $searchNode),2)"/>
    				</xsl:call-template>
    			</xsl:for-each>
    		</xsl:when>
    		<xsl:when test="starts-with($xpath, '/')">
    			<xsl:variable name="temp" select="substring-after($xpath,'/')"/>
    			<xsl:variable name="searchNode">
    				<xsl:choose>
    					<xsl:when test="contains($temp, '/')">
    						<xsl:value-of select="substring-before($temp, '/')"/>
    					</xsl:when>
    					<xsl:otherwise>
    						<xsl:value-of select="$temp"/>
    					</xsl:otherwise>
    				</xsl:choose>
    			</xsl:variable>
    			<xsl:if test="/*[name() = $searchNode]">
    				<xsl:call-template name="evaluate">
    					<xsl:with-param name="context" select="/*"/>
    					<xsl:with-param name="xpath" select="substring(substring-after($temp, $searchNode),2)"/>
    				</xsl:call-template>
    			</xsl:if>
    		</xsl:when>
    		<xsl:when test="contains($xpath, '/')">
    			<xsl:variable name="nodeName" select="substring-before($xpath,'/')"/>
    			<xsl:for-each select="./*[name() = $nodeName]">
    				<xsl:call-template name="evaluate">
    					<xsl:with-param name="xpath" select="substring-after($xpath, '/')"/>
    				</xsl:call-template>
    			</xsl:for-each>
    		</xsl:when>
    		<xsl:otherwise>
    			<xsl:value-of select="*[name() = $xpath]"/>
    		</xsl:otherwise>
    	</xsl:choose>
    </xsl:template>
    I couldn't find it, so I wrote this instead.
    Takes xpaths in forms
    node
    node/child/nextchild
    /root/node
    //nodeAnywhere/node

    etc.
    Wildcards * not accepted.
    Last edited by jkmyoung; 08-16-2007 at 12:41 PM.

  6. #6
    Join Date
    Aug 2007
    Posts
    4
    Thanks! I'll try this asap and let you know. It looks good, though!

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
HTML5 Development Center



Recent Articles