|
Subject:
|
document(), attribute and name() match
|
|
Posted By:
|
perropicante
|
Post Date:
|
6/13/2003 8:11:48 PM
|
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.
<?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
<?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...<?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
|
|
Reply By:
|
armmarti
|
Reply Date:
|
6/14/2003 4:56:31 AM
|
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
|
|
Reply By:
|
perropicante
|
Reply Date:
|
6/14/2003 1:33:22 PM
|
Thanks, it worked great. And thanks for the explanation ;)
Mike
|
|
Reply By:
|
JavaBurre
|
Reply Date:
|
9/10/2003 8:29:17 AM
|
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
|
|
Reply By:
|
Yehuda
|
Reply Date:
|
9/10/2003 8:53:18 AM
|
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
|
|
Reply By:
|
falmouth
|
Reply Date:
|
11/16/2004 11:59:39 AM
|
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?
|
|
Reply By:
|
jkmyoung
|
Reply Date:
|
11/16/2004 12:57:29 PM
|
name is a function; put the name around the rest eg:
select="name($structure/*[@id=name(current())])"
|
|
Reply By:
|
falmouth
|
Reply Date:
|
11/16/2004 2:05:35 PM
|
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!
|
|
Reply By:
|
joefawcett
|
Reply Date:
|
11/17/2004 6:14:07 AM
|
If you don't specify a path then it uses the context node.
--
Joe (Microsoft MVP - XML)
|