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 gkittelson 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
Aug 2, 2002
1,291
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