Wrox Programmer Forums
Go Back   Wrox Programmer Forums > XML > XSLT
|
XSLT General questions and answers about XSLT. For issues strictly specific to the book XSLT 1.1 Programmers Reference, please post to that forum instead.
Welcome to the p2p.wrox.com Forums.

You are currently viewing the XSLT section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
 
Old June 13th, 2003, 08:11 PM
Registered User
 
Join Date: Jun 2003
Posts: 8
Thanks: 0
Thanked 0 Times in 0 Posts
Default document(), attribute and name() match

I've got a relatively simple concept going here: I have one xml document with tags that I want to translate into more meaningful words. The translations are in another xml document. An XSL transformation takes care of matching the tag to its translation.

Here's (part of) the XML document that needs its tags translated.
Code:
<?xml version="1.0" encoding="UTF-8"?>
<NewDataSet>
    <Person>
        <id>1</id>
        <firstname>Michael</firstname>
        <lastname>Gradek</lastname>
        <birthdate>1980-11-13T00:00:00.0000000-05:00</birthdate>
    </Person>
</NewDataSet>
Here's the XML document that does the translation
Code:
<?xml version="1.0" encoding="UTF-8"?>
<localization>
    <datatranslations>
        <element name="firstname">
            <en>First Name</en>
            <fr>Prénom</fr>
        </element>
        <element name="lastname">
            <en>Last Name</en>
            <fr>Nom</fr>
        </element>
        <element name="birthdate">
            <en>Birth Date</en>
            <fr>Date de Naissance</fr>
        </element>
    </datatranslations>
</localization>
Here's the XSL that fails...
Code:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
<xsl:param name="localization_url" select="'blackbook_localization.xml'" />
<xsl:variable name="trans_doc" select="document($localization_url)/localization/datatranslations" />


<xsl:template match="/">
    <xsl:call-template name="simpledisplay" />
</xsl:template>


<xsl:template name="simpledisplay">
    <xsl:for-each select="//NewDataSet/*">
        <div style="border: 1px solid #FF0000;">
            <xsl:for-each select="*[not(contains(name(), 'id'))]">
                <xsl:value-of select="name()" />:
                <xsl:value-of select="$trans_doc/element[@name=name()]/en" />:
                <xsl:value-of select="." />
                <br />
            </xsl:for-each>
        </div>
    </xsl:for-each>
</xsl:template>

</xsl:stylesheet>
The problem is the line
<xsl:value-of select="$trans_doc/element[@name=name()]/en" />
It returns nothing.

$trans_doc/element works properly, I'm able to iterate through its contents.
All the @name attributes have values, and all the calls to name() also return the proper values.

If I type <xsl:value-of select="$trans_doc/element[@name='firstname']/en" />, I get the expected result, same for <xsl:value-of select="$trans_doc/element[@name='lastname']/en" />.

But when I use name() instead of hardcoding the value, it fails... What am I doing wrong?

Thanks for your help!
Mike
 
Old June 14th, 2003, 04:56 AM
Friend of Wrox
 
Join Date: Jun 2003
Posts: 147
Thanks: 0
Thanked 0 Times in 0 Posts
Send a message via Yahoo to armmarti
Default

Hi,
the trick is that in the XPath $trans_doc/element[@name=name()] the function "name()" returns the name of the context node, which is "element", so you compare attribute values with string "element". Replace the line with the following and it must work:

<xsl:value-of select="$trans_doc/element[@name=name(current())]/en" />

Now, you compare the attribute value with the current node's name.

Regards,
Armen
 
Old June 14th, 2003, 01:33 PM
Registered User
 
Join Date: Jun 2003
Posts: 8
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Thanks, it worked great. And thanks for the explanation ;)

Mike
 
Old September 10th, 2003, 08:29 AM
Registered User
 
Join Date: Sep 2003
Posts: 1
Thanks: 0
Thanked 0 Times in 0 Posts
Default

I have a simular problem so I post it to this topic.

In my situation the value to retrieve is in an attribute.
So I try something like this:

<xsl:value-of select="$trans_doc/element[@name=name(current())]@en"/>

But when I run this I get the error (java Xalan):
Fatal Error! Extra illegal tokens: '@', 'en'
Fatal Error! Fatal error during transformation Cause: Fatal error
during transformation
Without the attribute part it processes (but off course not the wanted result).

What did I do wrong ?

Regards,

JavaBurre

 
Old September 10th, 2003, 08:53 AM
Friend of Wrox
 
Join Date: Aug 2003
Posts: 205
Thanks: 0
Thanked 0 Times in 0 Posts
Default

I believe you are missing a '/' before the @. I think you want this:

<xsl:value-of select="$trans_doc/element[@name=name(current())]/@en"/>

Yehuda
 
Old November 16th, 2004, 12:59 PM
Registered User
 
Join Date: Nov 2004
Posts: 5
Thanks: 0
Thanked 0 Times in 0 Posts
Default

I have a problem along the sames lines as this. My present XSL code is:

<xsl:element name="test">
    <xsl:choose>
        <xsl:when test="$structure/*[@id=name(current())]"><xsl:value-of select="$structure/*[@id=name(current())]/@label" /></xsl:when>
        <xsl:otherwise>unknown</xsl:otherwise>
    </xsl:choose>
</xsl:element>

The above code works fine. However, I really want it to return the name() of the matching node, rather than the value of its @label attribute - but, when I change @label to name(), I get the following error:

NodeTest expected here. $structure/*[@id=name(current())]/-->name<--()

Does anyone have any suggestions or alternative solutions?

 
Old November 16th, 2004, 01:57 PM
Authorized User
 
Join Date: Nov 2004
Posts: 81
Thanks: 0
Thanked 0 Times in 0 Posts
Send a message via ICQ to jkmyoung
Default

name is a function; put the name around the rest eg:

select="name($structure/*[@id=name(current())])"

 
Old November 16th, 2004, 03:05 PM
Registered User
 
Join Date: Nov 2004
Posts: 5
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Perfect! Thank you so much. I spent most of the day trying to work that out.

So, when it comes to XSL functions, such as name(), you specify your XPath between the brackets! Worth remembering. Thanks!

 
Old November 17th, 2004, 07:14 AM
joefawcett's Avatar
Wrox Author
 
Join Date: Jun 2003
Posts: 3,074
Thanks: 1
Thanked 38 Times in 37 Posts
Default

If you don't specify a path then it uses the context node.


--

Joe (Microsoft MVP - XML)





Similar Threads
Thread Thread Starter Forum Replies Last Post
Replace an attribute with another attribute georgemeng XSLT 8 June 10th, 2008 11:04 AM
template match doesnt match the required node Tomi XSLT 2 March 12th, 2007 06:24 AM
Match by attribute. ole_v2 XSLT 6 November 11th, 2006 10:24 AM
Access to attribute values from class of attribute jacob C# 1 October 28th, 2005 01:11 PM
Match element based on attribute of child? transom XSLT 1 September 11th, 2005 03:26 PM





Powered by vBulletin®
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
Copyright (c) 2020 John Wiley & Sons, Inc.