Passing variable node name to XSL "select" clause

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • paragpdoke
    New Member
    • Dec 2007
    • 62

    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:
    Code:
    <root>
    <ObjectTemplate>
    <NodeType1></NodeType1>
    <NodeType2></NodeType2>
    </ObjectTemplate>
    <Object>
    <NodeType1>N11</NodeType1>
    <NodeType2>N12</NodeType2>
    </Object>
    <Object>
    <NodeType1>N21</NodeType1>
    <NodeType2>N22</NodeType2>
    </Object>
    </root>
    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:elemen t", I could build 2 drop downs. But I cannot figure out how to pass the select clause a different node type.
    Code:
    <xsl:for-each select="/root/ObjectTemplate/*">
    <xsl:element name="select">
    <xsl:variable name="myNodeType"><xsl:value-of select="name(.)"/></xsl:variable>
    <xsl:for-each select="concat('/root/Object/',$myNodeType)">
    <xsl:element name="option"><xsl:value-of select="."/></xsl:element>
    </xsl:for-each>
    </xsl:element>
    </xsl:for-each>
    Line 4 is probably what is wrong in my approach. Any help in this regard is welcome.
    Thanks in advance,
    Parag
  • jkmyoung
    Recognized Expert Top Contributor
    • Mar 2006
    • 2057

    #2
    [code=xml]
    <xsl:for-each select="/root/ObjectTemplate/*">
    <xsl:element name="select">
    <xsl:variable name="myNodeTyp e"><xsl:valu e-of select="name(.) "/></xsl:variable>
    <xsl:for-each select="/root/Object/*[local-name()=$myNodeT ype]">
    <xsl:element name="option">< xsl:value-of select="."/></xsl:element>
    </xsl:for-each>
    </xsl:element>
    </xsl:for-each>
    [/code]

    Comment

    • paragpdoke
      New Member
      • Dec 2007
      • 62

      #3
      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.blog spot.com

      Comment

      • paragpdoke
        New Member
        • Dec 2007
        • 62

        #4
        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:
        Code:
        <root>
        <ObjectTemplate>
        <NodeType1></NodeType1>
        <NodeType2></NodeType2>
        </ObjectTemplate>
        <Object>
        <NodeType1>N11</NodeType1>
        <NodeType2>N12</NodeType2>
        </Object>
        <Object>
        <NodeType1>N21</NodeType1>
        <NodeType2>N22</NodeType2>
        </Object>
        <Object>
        <NodeType1>N11</NodeType1>
        <NodeType2>N22</NodeType2>
        </Object>
        </root>
        The XSL I was trying to use:
        Code:
        <xsl:for-each select="/root/ObjectTemplate/*">
        <xsl:element name="select">
        <xsl:variable name="myNodeType"><xsl:value-of select="name(.)"/></xsl:variable>
        <xsl:for-each select="/root/Object/*[local-name()=$myNodeType and not(.=preceding::$myNodeType)]">
        <xsl:element name="option"><xsl:value-of select="."/></xsl:element>
        </xsl:for-each>
        </xsl:element>
        </xsl:for-each>
        I also tried
        Code:
        <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.ht ml]

        Thanks in advance once again,
        Parag P. Doke

        Comment

        • jkmyoung
          Recognized Expert Top Contributor
          • Mar 2006
          • 2057

          #5
          Close:
          [code=xml]
          <xsl:for-each select="/root/Object/*[local-name()=$myNodeT ype and not(.=preceding ::*[local-name()=$myNodeT ype])]">
          [/code]

          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.

          Comment

          • paragpdoke
            New Member
            • Dec 2007
            • 62

            #6
            Generating the select clause on the fly

            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".

            Comment

            Working...