8

Don't shoot I'm just the messenger here, but I have some xml that looks like this

<XMLSnippet>
    <data>
        <stuff value="stuff" />
        <stuff value="more stuff" />
        <stuff value="even more stuff" />
        <widget value="you expected stuff didn't you" />
        <stuff value="great, we've got stuff again" />
    </data>
</XMLSnippet>

And I would like to loop through all the data child nodes and output the following

stuff
more stuff
even more stuff
you expected stuff didn't you
great, we've got stuff again

Should it matter I am limited to using XSLT 1.0

Thanks!

dscl
  • 1,616
  • 7
  • 28
  • 48
  • Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance. – ApplePie Sep 09 '13 at 21:09
  • @AlexandreP.Levasseur - I would happily provide the XSLT code I've written except I have none as I don't know how to approach the problem. – dscl Sep 09 '13 at 21:10
  • Well what part exactly are you have trouble with ? Do you know how to select all `data` elements given the structure ? Do you know how to select only attributes of elements given an XPath query that returned all the relevant elements ? – ApplePie Sep 09 '13 at 21:15
  • @AlexandreP.Levasseur - My issue is if I loop through the 'stuff' nodes as illustrated by Phil in his answer the 'widget' node will not be output in the proper location. I need to find a way to loop through children node not by their type(?), but by all children of the data node. – dscl Sep 09 '13 at 23:54
  • Just replace his `data/stuff` by `data` and his `@value` by `*/@value`. From what I remember this should do the trick. – ApplePie Sep 10 '13 at 00:53
  • That was very close! I toyed around with it a bit and got it working. Going to answer with the code below. – dscl Sep 10 '13 at 01:05

2 Answers2

22

Thanks to Phil and the suggestions of Alexandre here is the code I got working

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:template match="/XMLSnippet">
       <xsl:for-each select="data/*">
          <xsl:value-of select="@value" />
       </xsl:for-each>
   </xsl:template>
</xsl:stylesheet>
dscl
  • 1,616
  • 7
  • 28
  • 48
13

This is a basic XSLT question, so I am assuming you have little experience with xsl by your post. You need to understand how xslt processes a XML document which is beyond the scope of this post. Nevertheless, this should get you started. Please note, there are several ways to get the output you want, this is only one of them:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
<xsl:template match="/">
    <xsl:apply-templates/>
</xsl:template>
<xsl:template match="XMLSnippet">
    <xsl:for-each select="data/stuff">
        <xsl:value-of select="@value"/>
    </xsl:for-each>
</xsl:template>

For starters, the template match="/" is your entry point. The apply-templates is an xslt instruction that tells the xslt processor to apply the template of the node in context. In this case your root node "XMLSnippet".

The for-each select="data/stuff" should be self explanatory as well as the value-of select="@value", except the @ is used to select an attribute.

Good Luck. May I suggest you read this book XSLT 2.0. A great book on XSLT.

PhillyNJ
  • 3,859
  • 4
  • 38
  • 64
  • 3
    You are correct that I have limited experience. My issue comes in with needing to display the 'widget' value as well. If I'm correct your code would only display the 'stuff' nodes. – dscl Sep 09 '13 at 23:53
  • 3
    Why is this answer marked correct? It seems that leaving out the 'widget' element in the looping construct would mean that the requirement of the question isn't addressed. – twindham Nov 10 '16 at 22:02
  • @twindham - In xslt you simply do not "loop" through nodes, you visit nodes. As for the answer, I showed the OP how to select each node. In this case, `data/stuff`, are the nodes. It is assumed that this would be enough and since they marked it as answered, then it was. – PhillyNJ Nov 10 '16 at 22:16
  • 1
    @PhillyNJ your comment is correct. I should have addressed my question to dscl. His first comment on this thread states that your solution doesn't visit the 'widget' value as desired. Then he goes on and adds a separate answer to this question that does successfully visit all of his 'stuff' elements and 'widget' element. It just seems logical to me that his answer to this question should be marked correct instead of yours. Is there something I'm missing in my thought process here? – twindham Nov 10 '16 at 22:28
  • @twindham no worries. I answered his question taught him something in the process. He then answered his own question and gave me credit. I think it's fair. – PhillyNJ Nov 10 '16 at 22:35