Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chriss Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Creating attributes from 'n' number of nodes 1

Status
Not open for further replies.

csteinhilber

Programmer
Joined
Aug 2, 2002
Messages
1,291
Location
US
This probably doesn't fall under "best practices", but, again, I'm trying to work with legacy data here.

I have XML that looks like:
Code:
  :
<fields>
   <field>
      <type>checkbox</type>
      <name>name 1</name>
      <checked>checked</checked>
      <label>Checkbox 1</label>
      <id>1234</id>
   </field>
   <field>
      <type>text</type>
      <name>name 2</name>
      <value>Default value</value>
   </field>
   <field>
      <type>checkbox</type>
      <name>name 3</name>
      <label>Checkbox 2</label>
      <value>Yes</value>
      <onClick>someFunction()</onClick>
   </field>

</fields>
  :

I would like to be able to transform this into an HTML form, with the preferred output being
Code:
   <input type="checkbox" name="name 1" checked="checked" id="1234" /> Checkbox 1<br />
   <input type="text" name="name 2" value="Default value" /><br />
   <input type="checkbox" name="name 3" value="Yes" onClick="someFunction()" /> Checkbox 2<br />

As you can see, each field will have different sets of nodes... which will hopefully translate directly to different sets of attributes for the HTML tags. So I really want an XSL template that is generic enough to handle whatever nodes are present and ignore those that aren't.

I thought of something like
Code:
      :
   <xsl:apply-templates select="fields/*" />
      :

   <xsl:template match="field">
	<input>
	    <xsl:for-each select="./*">
		<xsl:attribute name="name()">
		    <xsl:value-of select="@name()" />
		</xsl:attribute>
	    </xsl:for-each>
        </input>
   </xsl:template>

But, of course, it doesn't work in real life.

If there a way to dynamically produce attributes (in this case for the input tag) based on the name/value pairs of an unknown number of nodes?

Thanks in advance!



-Carl
 
You're almost there.
Code:
<xsl:attribute name="[COLOR=red]local-name()[/color]">
    <xsl:value-of select="[COLOR=red].[/color]" />
</xsl:attribute>
Untested!

Tom Morrison
 
Hmmmm... thanks Tom... but it didn't seem to work.

Code:
   <input>
      <xsl:for-each select="./*">
        <xsl:attribute name="local-name()">
            <xsl:value-of select="." />
        </xsl:attribute>
      </xsl:for-each>
   </input><br />

for me, produces
Code:
    <input/><br/>
    <input/><br/>
    <input/><br/>

Do I have something amiss with the for-each?



-Carl
 
Ack. Still not working properly.

I think the for-each select is actually correct, because when I try to hard code the attribute name... such as:
Code:
  <input>
     <xsl:for-each select="./*">
        <xsl:attribute name="[COLOR=#ff0000][b]value[/b][/color]">
	    <xsl:value-of select="." />
	</xsl:attribute>
     </xsl:for-each>
  </input><br />

I get the somewhat expected output of
Code:
<input value="1234"/><br/>
<input value="Default value"/><br/>
<input value="someFunction()"/><br/>

So I know it's looping over the correct elements, and the value-of select="." is pulling the proper values.

Seems the only thing that's not working is being able to grab the name of the proper element. Neither name() or local-name() seem to be doing it.


-Carl
 
GOT IT! :D

Code:
   <input>
     <xsl:for-each select="./*">
        <xsl:attribute name="[b]{[/b]local-name()[b]}[/b]">
           <xsl:value-of select="." />
        </xsl:attribute>
     </xsl:for-each>
   </input><br />

works. The odd thing is I'm relative sure I'd tried it any number of times already. Oh well.

Also odd, though...
Code:
   :
        <xsl:attribute name="{[b]name()[/b]}">
   :
works just as well. Not sure why.



-Carl
 
Thanks Tom... looks like we hit on the answer at the same time ;)

Went ahead and gave you a star because you definitely pointed me in the right direction!

Thanks again!


-Carl
 
These are called attribute value templates and it is high on my "most often miscoded" list.

name will include the namespace modifier prefix if present, whereas local-name does not. Consider the element <xsl:value-of .../>. The local-name returns value-of whereas name returns xsl:value-of.

XPath -- gotta love it...

Tom Morrison
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top