Jump to content

It's possible to do this??


PRF

Recommended Posts

Hello, i think that this is a limitation of XSLT, if not, i'll appreciate your help.This is the XML example:<pets><cats>3</cats><dogs>2</dogs><parrots>2</parrots><turtles>5</turtles></pets>I need build this table:Pets |amountcats | 3dogs | 2parrot | 2turtles | 5thanks for yours answers!

Link to comment
Share on other sites

<pets amount="12"><cats>3</cats><dogs>2</dogs><parrots>2</parrots><turtles>5</turtles></pets>Is this what you are after? If so, you'd have to loop through the pet types forst to get their total, then loop through them again to get their total.Of course, you could always skip that and do this:<pets><cats>3</cats><dogs>2</dogs><parrots>2</parrots><turtles>5</turtles><amount>12</amount></pets>But that all depends on your structure requirements and what/how you plan on doing with it.

Link to comment
Share on other sites

yes, i'd have to loop through the pet types,but not for counting them, is to show them, becouse the types of pets can change when the XML is generated.so, i need the XSL code to build that table whit that XML, i can build a table but the rows are the "tag content value" (<tag_name>tag_content</tag_name> i need to row tag_name | tag_content.i explain myself well?is this possible?thanks again.

Link to comment
Share on other sites

It's possible by replacing the node name with "fn:name". However, for some reason, I seem to be unable to allocate the namespace where the XPath functions are and because of that, every document in which I use a function returns an error... I'll keep looking.

Link to comment
Share on other sites

<xsl:template match="/pets"><table width="200" border="1"><xsl:for-each select="//">  <tr>    <td><xsl:value-of select="fn:name()" /></td>    <td><xsl:value-of select="fn:current()" /></td>  </tr></xsl:for-each></table></xsl:template>

I'm not sure, but I think if the functions were working this template would had returned what you want.

Link to comment
Share on other sites

fn:name() is a function which returns the name of the current node. Or atleast that's what it says. fn:current() is suppose to return the value of the current node... hm... maybe fn:current(fn:name())? Anyway... the main point is that you need to use XPath's functions which makes the things a lot harder when they could be so simpler... can't you make the XML look more... normal?

Link to comment
Share on other sites

You already said it yourself(well...kind of): use a consistant naming scheme and their respective values, so XSLT could fill the whole thing without the need of XPath functions:

<pets>  <pet>    <kind>cats</kind>    <quantity>3</quantity>  </pet>  <pet>    <kind>dogs</kind>    <quantity>2</quantity>  </pet>  <pet>    <kind>parrots</kind>    <quantity>2</quantity>  </pet>  <pet>    <kind>turtles</kind>    <quantity>5</quantity>  </pet></pets>

Link to comment
Share on other sites

For the sake of trying to solve this challenge, I was able to use few XPath functions. The only one which didn't worked was node-name() which is actually the ctutual one here. Both IE and FF say it's not a valid XPath function. Even adding the fn: prefix before it didn't work. It said that the namespace I provided(from the XPath referance) doesn't contain any XPath functions :) .

<xsl:stylesheet version="1.0"xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fn="http://www.w3.org/2005/02/xpath-functions"><xsl:template match="/"><html><head></head><body><table><xsl:for-each select="/Pets/node()">  <tr>    <td><xsl:value-of select="node-name(node())" /></td>    <td><xsl:value-of select="current()" /></td>  </tr></xsl:for-each></table></body></html></xsl:template></xsl:stylesheet>

Link to comment
Share on other sites

  • 2 weeks later...

I'm glad my offered structure worked and I hope you will always remember to use it. But I must say I just worked on this challenge again (the fact that your issue is solved with a completely new XML is not a thing which will make me sleep while thinking "job well done") and I finally got it perfectly. The following XSLT will output exactly what you wanted. Suggest it if someone has the same problem with already huge database (I understand that yours was just a test, but an already huge XML file is not something a user will thing to alter).

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><xsl:template match="/"> <html> <body><table>  <tr>    <td>Pets</td>    <td>Amount</td>  </tr><xsl:for-each select="/pets/*">  <tr>    <td><xsl:value-of select="local-name(current())" /></td>    <td><xsl:value-of select="current()" /></td>  </tr></xsl:for-each>  <tr>    <td>Total</td>	<td><xsl:value-of select="sum(pets/*)" /></td>  </tr></table></body> </html></xsl:template></xsl:stylesheet>

Link to comment
Share on other sites

thanks gurú!!! although my application is finished (with the other XML structure) i'm very grateful of your help. I'm impressed of your capabilities to investigate... i'll share this method who need.tnx again.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...