469,284 Members | 2,505 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,284 developers. It's quick & easy.

Passing variable node name to XSL "select" clause

Hello Everyone.
I'm new to XSL and couldn't get something to work. [Not sure if this is the right way to go about it...]
Sample XML excerpt:
Expand|Select|Wrap|Line Numbers
  1. <root>
  2. <ObjectTemplate>
  3. <NodeType1></NodeType1>
  4. <NodeType2></NodeType2>
  5. </ObjectTemplate>
  6. <Object>
  7. <NodeType1>N11</NodeType1>
  8. <NodeType2>N12</NodeType2>
  9. </Object>
  10. <Object>
  11. <NodeType1>N21</NodeType1>
  12. <NodeType2>N22</NodeType2>
  13. </Object>
  14. </root>
  15.  
My intent is to build a list of drop downs (# of drop downs = # of NodeTypes) based on those defined in the template. Using "xsl:for-each" and "xsl:element", I could build 2 drop downs. But I cannot figure out how to pass the select clause a different node type.
Expand|Select|Wrap|Line Numbers
  1. <xsl:for-each select="/root/ObjectTemplate/*">
  2. <xsl:element name="select">
  3. <xsl:variable name="myNodeType"><xsl:value-of select="name(.)"/></xsl:variable>
  4. <xsl:for-each select="concat('/root/Object/',$myNodeType)">
  5. <xsl:element name="option"><xsl:value-of select="."/></xsl:element>
  6. </xsl:for-each>
  7. </xsl:element>
  8. </xsl:for-each>
  9.  
Line 4 is probably what is wrong in my approach. Any help in this regard is welcome.
Thanks in advance,
Parag
Mar 15 '08 #1
5 6945
jkmyoung
2,057 Expert 2GB
Expand|Select|Wrap|Line Numbers
  1. <xsl:for-each select="/root/ObjectTemplate/*">
  2. <xsl:element name="select">
  3. <xsl:variable name="myNodeType"><xsl:value-of select="name(.)"/></xsl:variable>
  4. <xsl:for-each select="/root/Object/*[local-name()=$myNodeType]">
  5. <xsl:element name="option"><xsl:value-of select="."/></xsl:element>
  6. </xsl:for-each>
  7. </xsl:element>
  8. </xsl:for-each>
  9.  
Mar 17 '08 #2
Hello jkmyoung.
Thank you very much for the reply. It is working for me.
[Apologies for the delayed response. Somehow instant email notification preference is not working for my thescripts login.]

Regards,
Parag P. Doke
http://paragpdoke.blogspot.com
Mar 21 '08 #3
I am sorry for reposting. But...my attempts to get only distinct values populated in the drop downs went futile. Here's the new code:
Expand|Select|Wrap|Line Numbers
  1. <root>
  2. <ObjectTemplate>
  3. <NodeType1></NodeType1>
  4. <NodeType2></NodeType2>
  5. </ObjectTemplate>
  6. <Object>
  7. <NodeType1>N11</NodeType1>
  8. <NodeType2>N12</NodeType2>
  9. </Object>
  10. <Object>
  11. <NodeType1>N21</NodeType1>
  12. <NodeType2>N22</NodeType2>
  13. </Object>
  14. <Object>
  15. <NodeType1>N11</NodeType1>
  16. <NodeType2>N22</NodeType2>
  17. </Object>
  18. </root>
  19.  
The XSL I was trying to use:
Expand|Select|Wrap|Line Numbers
  1. <xsl:for-each select="/root/ObjectTemplate/*">
  2. <xsl:element name="select">
  3. <xsl:variable name="myNodeType"><xsl:value-of select="name(.)"/></xsl:variable>
  4. <xsl:for-each select="/root/Object/*[local-name()=$myNodeType and not(.=preceding::$myNodeType)]">
  5. <xsl:element name="option"><xsl:value-of select="."/></xsl:element>
  6. </xsl:for-each>
  7. </xsl:element>
  8. </xsl:for-each>
  9.  
I also tried
Expand|Select|Wrap|Line Numbers
  1. <xsl:for-each select="/root/Object/*[local-name()=$myNodeType and not(.=preceding::local-name(.))]">
...but that too did not work :-(.

How can I get the drop downs to have only distinct values ? [Pardon my lack of knowledge, I have copied the preceding:: thing from elsewhere. Still reading XSL tutorials to get to know more about axes.]

Also, my 2nd question is: What is the difference between local-name() and name() functions ? When I tried using name(), it worked in similar manner.

Someone told me that it made sense to create a DTD file for all possible values instead of generating a list of distinct ones from the data in the XML file. But in this context of building the drop downs and populating them from a DTD, I have more questions:
- How to capture information inside DTD using XSL ?
- How to restrict values of a node to some pre-defined set ? [http://www.thescripts.com/forum/thread785602.html]

Thanks in advance once again,
Parag P. Doke
Mar 22 '08 #4
jkmyoung
2,057 Expert 2GB
Close:
Expand|Select|Wrap|Line Numbers
  1. <xsl:for-each select="/root/Object/*[local-name()=$myNodeType and not(.=preceding::*[local-name()=$myNodeType])]">
  2.  
name() only gives you something different if it has a namespace attached.

For example, take node: <xsl:value-of/>
name is xsl:value-of
local-name is value-of


I'm not really good at DTD, but will have a look at the other question.
Mar 24 '08 #5
Hi again.
Thank you for the explanation regarding name() and local-name().
Also, if I run into something helpful, I'll make sure I add to this post.

Regards,
Parag P. Doke

P.S.: I guess I should have had the title of this post as "Generating the select clause on the fly" rather than "Passing variable node name to XSL "select" clause".
Mar 25 '08 #6

Post your reply

Sign in to post your reply or Sign up for a free account.

Similar topics

reply views Thread by zhoujie | last post: by
reply views Thread by suresh191 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.