0

Here is my feed

<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-stylesheet type="text/xsl" href="feedstylev5.xsl"?>
<feed >

   <Layout>
        <breakingnews>
               <story id="112345" rank="1">Story Title 1</story>
                <story id="122345" rank="2">Story Title 1</story>
                <story id="212345" rank="3">Story Title 2</story>

        </breakingnews>

        <topnews>
                <story id="012345" rank="1">Story Title 1</story>
                <story id="117345" rank="2">Story Title 1</story>
                <story id="612345" rank="3">Story Title 1</story>
                <story id="712345" rank="4">Story Title 1</story>

        </topnews>

        <news>
                <story id="012345" rank="1">Story Title 1</story>
                <story id="117345" rank="2">Story Title 1</story>
                <story id="612345" rank="3">Story Title 1</story>
                <story id="312145" rank="4">Story Title 1</story>
                <story id="412045" rank="5">Story Title 1</story>
        </news>

        <sports>
                <story id="712345" rank="1">Story Title 1</story>
                <story id="912345" rank="2">Story Title 1</story>
                <story id="812345" rank="3">Story Title 1</story>
                <story id="102345" rank="4">Story Title 1</story>
                <story id="212245" rank="5">Story Title 1</story>
        </sports>



   </Layout>
</feed>

What I am trying to do is loop through the story and where the breaking news,sports tag i want to display the tag itself instead of hard coding like I have below.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:atom="http://www.w3.org/2005/Atom">

<xsl:template match="/feed">
  <html>
  <body>


   <h2 style="font-style:italic; font-weight:bold;">Breaking News</h2>

    <xsl:for-each select="Layout/breakingnews/story">

      <div style="float:left; margin-left:25px; margin-right:5px;"><xsl:value-of select="@rank"/></div>
      <div style="float:left;"> <xsl:value-of select="."/></div>
      <div style="float:left;">(<xsl:value-of select="@id"/>)</div>
      <div style="clear:both;"></div>    
    </xsl:for-each>




  </body>
  </html>
</xsl:template>

</xsl:stylesheet>

I want to replace breaking news with variable as the value is going to change and want make it loop through.

2
  • I understand what you are asking to do, but how do you expect the XSL to turn the tag name "breakingnews" into "Breaking News"? Commented Jan 8, 2013 at 4:44
  • How about use here <xsl:variable name="tag" select="'breakingnews'"/> and then put into for-each like <xsl:for-each select="Layout/{$tag}/story"> ? Commented Jan 8, 2013 at 4:53

2 Answers 2

2

My recommendation is to do something like the following - move the for-each logic into a template:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:atom="http://www.w3.org/2005/Atom">

    <xsl:template match="/feed">
        <html>
            <body>
                <h2 style="font-style:italic; font-weight:bold;">Breaking News</h2>
                <xsl:apply-templates select="Layout/breakingnews/story"/>

                <h2 style="font-style:italic; font-weight:bold;">Top News</h2>
                <xsl:apply-templates select="Layout/topnews/story"/>

            </body>
        </html>
    </xsl:template>

    <xsl:template match="story">
        <div style="float:left; margin-left:25px; margin-right:5px;">
            <xsl:value-of select="@rank"/>
        </div>
        <div style="float:left;">
            <xsl:value-of select="."/>
        </div>
        <div style="float:left;">
            (<xsl:value-of select="@id"/>)
        </div>
        <div style="clear:both;"></div>                
    </xsl:template>

</xsl:stylesheet>
Sign up to request clarification or add additional context in comments.

6 Comments

Thank you that worked but is also possible to use a variable breaking news and top news and the feed will change and I do not want to hard code the titles as this feed will be changing sections and need to loop through with variable in that spot.
I'd also be a bit concerned if my feed was changing - how would you know what parameters to pass in anyway? That routine would have to be updated. An alternative would be to do the parsing in server-side code
maybe not changing is the best way to put it. Some days there will not be s sport sections as other days might not be a breaking news and do not want to have to hard code the titles. I was thinking doing a loop for each section and use a variable so I can print the variable for each section title.
i found '<xsl:value-of select="local-name()"/>' and like to use this to display the sections name like breaking news or sports.
|
0

It it possible to change the XML structure? If so, I would suggest changing the XML to be like this:

<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-stylesheet type="text/xsl" href="feedstylev5.xsl"?>
<feed >

   <Layout>
        <section code="breakingnews" title="Breaking News">
               <story id="112345" rank="1">Story Title 1</story>
                <story id="122345" rank="2">Story Title 1</story>
                <story id="212345" rank="3">Story Title 2</story>

        </section>

        <section code="topnews" title="Top News">
                <story id="012345" rank="1">Story Title 1</story>
                <story id="117345" rank="2">Story Title 1</story>
                <story id="612345" rank="3">Story Title 1</story>
                <story id="712345" rank="4">Story Title 1</story>

        </section>

        ...  

   </Layout>
</feed>

And then make your XSLT like this:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:atom="http://www.w3.org/2005/Atom">
  <xsl:template match="/feed">
    <html>
      <body>

        <xsl:apply-templates select="Layout/section" />

      </body>
    </html>
  </xsl:template>

  <xsl:template match="section">
    <h2 style="font-style:italic; font-weight:bold;">
      <xsl:value-of select="@title" />
    </h2>
    <xsl:apply-templates select="story" />
  </xsl:template>

  <xsl:template match="story">
    <div style="float:left; margin-left:25px; margin-right:5px;">
      <xsl:value-of select="@rank"/>
    </div>
    <div style="float:left;">
      <xsl:value-of select="."/>
    </div>
    <div style="float:left;">
      (<xsl:value-of select="@id"/>)
    </div>
    <div style="clear:both;"></div>
  </xsl:template>
</xsl:stylesheet>

The code= attributes are not actually used above, but I would advise having them for good measure.

If you can't modify the input XML structure, then your next best bet would be to change the first two templates in my example to be like this:

  <xsl:template match="/feed">
    <html>
      <body>

         <xsl:call-template name="Section">
           <xsl:with-param name="section" select="Layout/breakingnews" />
           <xsl:with-param name="title" select="'Breaking News'" />
         </xsl:call-template>
         <xsl:call-template name="Section">
           <xsl:with-param name="section" select="Layout/topnews" />
           <xsl:with-param name="title" select="'Top News'" />
         </xsl:call-template>
         <xsl:call-template name="Section">
           <xsl:with-param name="section" select="Layout/news" />
           <xsl:with-param name="title" select="'News'" />
         </xsl:call-template>
         <xsl:call-template name="Section">
           <xsl:with-param name="section" select="Layout/sports" />
           <xsl:with-param name="title" select="'Sports'" />
         </xsl:call-template>

      </body>
    </html>
  </xsl:template>

  <xsl:template name="Section">
    <xsl:param name="section" />
    <xsl:param name="title" />
    <h2 style="font-style:italic; font-weight:bold;">
      <xsl:value-of select="$title" />
    </h2>
    <xsl:apply-templates select="story" />
  </xsl:template>

This will omit any sections that aren't in the feed at any given time, but would require you to hardcode the titles in the XSL and their order would be fixed.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.