Welcome to WebmasterWorld Guest from 54.160.177.33

Forum Moderators: httpwebwitch

Message Too Old, No Replies

XML & XSLT assistance

     
9:25 am on Sep 23, 2008 (gmt 0)

Full Member

10+ Year Member

joined:July 27, 2005
posts:329
votes: 0


I'm pulling an XML feed into a page and I can only get the whole feed to display. All I want is a few of the elements.

Example XML feed:


<?xml version="1.0" encoding="UTF-8"?>
<info xmlns="http://www.exmaple.com/info">
<result>1</result>
<item>
<name>name</name>
<img>img</img>
<related>
<id>id</id>
</related>
<related>
<id>id</id>
</related>
<related>
<id>id</id>
</related>
</item>
</info>

Example XSL file:


<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" omit-xml-declaration="yes"/>
<xsl:template match="info">
<xsl:for-each select="/item">
<h3>Item</h3>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>

When I run this through an XSLT debugger as XHTML the whole feed is returned. I have also tried:

<xsl:template match="/">
<xsl:apply-templates/>
</xsl:template>

which didn't work.

Am I doing something obviously wrong (the incorrect use of "/s" e.g. when should one use /info/item vs /item?)

[edited by: httpwebwitch at 11:46 am (utc) on Sep. 23, 2008]
[edit reason] removed smilies [/edit]

11:48 am on Sept 23, 2008 (gmt 0)

Moderator This Forum from CA 

WebmasterWorld Administrator httpwebwitch is a WebmasterWorld Top Contributor of All Time 10+ Year Member

joined:Aug 29, 2003
posts:4059
votes: 0


try "item" instead of "/item"
1:26 pm on Sept 23, 2008 (gmt 0)

Moderator This Forum from CA 

WebmasterWorld Administrator httpwebwitch is a WebmasterWorld Top Contributor of All Time 10+ Year Member

joined:Aug 29, 2003
posts:4059
votes: 0


sorry, that was a really hasty reply. I haven't actually tested your sample, or my suggestion, in an XSLT debugger.

I'm guessing the problem is just the XPATH in your for-each. While you're inside the "info" template, you're in the "info" scope. So your XPATH, relative to "info", is "item", since item is a direct child of info. It's a lot like defining relative paths or URLs; you can define an XPATH relative to the context of the current node of template you're in.

"item" matches an item as the child of whatever the current node is. "/item" tells XPATH to look for an item at the root node. "//item" would match an item anywhere in the tree.

I hope that makes enough sense. If you can't crack this one quickly, reply back.

1:29 pm on Sept 23, 2008 (gmt 0)

Full Member

10+ Year Member

joined:July 27, 2005
posts:329
votes: 0


Thanks, httpwebwitch, but no luck. Nothing seems be be filtering through.
1:35 pm on Sept 23, 2008 (gmt 0)

Full Member

10+ Year Member

joined:July 27, 2005
posts:329
votes: 0


Thanks for your second response, httpwebwitch (only just saw it). Still not able to crack this.
10:49 am on Oct 2, 2008 (gmt 0)

Full Member

10+ Year Member

joined:July 27, 2005
posts:329
votes: 0


Had to specify the corresponding namespace in the XML and use it as a prefix on each parameter for this to work.

I have a related question. How do I substitute spaces in the XML with underscores?

e.g. XML file contains "The cumulus cloud"
but I need it to return as "The_cumulus_cloud"

This is what I've tried:


<xsl:variable name="cname"><xsl:value-of select="ab:name"/></xsl:variable>
<xsl:attribute name="src"><xsl:value-of select="translate($cname,'','_')"/>.jpg</xsl:attribute>
12:11 pm on Oct 2, 2008 (gmt 0)

Moderator This Forum from CA 

WebmasterWorld Administrator httpwebwitch is a WebmasterWorld Top Contributor of All Time 10+ Year Member

joined:Aug 29, 2003
posts:4059
votes: 0


The translate() function is the most efficient for simple character substitution.

There are also old-fashioned string replace templates [xml.com] you can try, if you're limited to using XSLT 1.0

in your example there isn't a space in the second parameter

translate($cname,' ','_')

that could be the problem
12:44 pm on Oct 2, 2008 (gmt 0)

Full Member

10+ Year Member

joined:July 27, 2005
posts:329
votes: 0


Well spotted & thank you, that was it. Thanks for sharing the link.
2:34 pm on Oct 2, 2008 (gmt 0)

Full Member

10+ Year Member

joined:July 27, 2005
posts:329
votes: 0


httpwebwitch, I have one more question.. I also had a look at the "Splitting and transforming strings" article on xml.com, but can't get this one figured out.

If I have comma separated values in the XML, how can I split these into divs?

e.g.

<c>cumulus,stratus,nimbus</c>

What I'd like to output is

<div class="c">
<div class="type" id="1">cumulus</div>
<div class="type" id="2">stratus</div>
<div class="type" id="3">nimbus</div>
</div>

The solution probably requires making use of a template, but what has thrown me off is the fact that there are only two commas, so I can't use

<xsl:value-of select="substring-before(., ':')"/>
or
<xsl:value-of select="substring-after(., ':')"/>

Thanks for your help.

5:56 pm on Oct 2, 2008 (gmt 0)

Moderator This Forum from CA 

WebmasterWorld Administrator httpwebwitch is a WebmasterWorld Top Contributor of All Time 10+ Year Member

joined:Aug 29, 2003
posts:4059
votes: 0


yeah... it's like you need a split() function for that. I wonder if one already exists out there in opensourceland?

That's one of the things that bothers me about XSLT - all the basic functions you expect to be available are missing. Things like replace() and split() and join() and stuff like that. It feels like trying to eat with only one chopstick.

But that's because I'm approaching XSLT being already familiar with OOP programming and scripting. It's actually a brilliant language... and XSLT2.0 is much better and fully-featured.

Unfortunately, PHP (my language of choice) doesn't have an XSLT2.0 parser

That last question is a neat XSLT challenge, and there are some lurkers here who enjoy a good XSLT challenge. Would you mind pasting it into a new thread?

Cheers

9:56 am on Oct 3, 2008 (gmt 0)

Full Member

10+ Year Member

joined:July 27, 2005
posts:329
votes: 0


Thanks for your response and helpful comments. I have created a new thread for the last question I had.