?
Solved

help grouping xml results

Posted on 2009-05-15
13
Medium Priority
?
251 Views
Last Modified: 2013-11-18
afternoon.

I would like to loop through my xml file and for each continent display the records that meet the $airline variable.

i.e. for each continent display each record where airline = Qantas.

and group these into individual tables.

get in contact to see the xml file.

cheers
0
Comment
Question by:d1114170
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 8
  • 5
13 Comments
 
LVL 60

Expert Comment

by:Geert Bormans
ID: 24396446
You can pass the variable to the XSLT
You can use a key to select nodes based on the value of the parameter

What do you have allready?
An XSLT
Can we see the XML?
0
 
LVL 60

Expert Comment

by:Geert Bormans
ID: 24396695
you could have a parameter
<xsl:param name="airline"/>
at the top level of your stylesheet

and a key
<xsl:key name="record-by-airline" match="record" use="airline"/>

and instead of doing
<xsl:apply-templates select="record"/>
in each continent

do
<xsl:apply-templates select="key('record', $airline)"/>

Or simply, if th grouping is not complex
<xsl:apply-templates select="record[airline = $airline]"/>
without the key


0
 

Author Comment

by:d1114170
ID: 24396703
here is the xml.
xml.txt
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 

Author Comment

by:d1114170
ID: 24397102
This is the part of my xsl that deals with this.
the template fares basically just styles and displays each row.

the parameter airline gets populated from an external cms.

<xsl:param name="airline">Air New Zealand</xsl:param>
<xsl:key name="record-by-airline" match="Fare" use="airline"/>

<xsl:template name="airlineFares">
  <xsl:variable name="fares" select="$airlineDisp" />
  <xsl:for-each select="Continent">
    <xsl:apply-templates select="Fare[airline = $airline]"/>
    <h2>
      <xsl:call-template name="Title">
        <xsl:with-param name="cid" select="CID"/>
      </xsl:call-template>
    </h2>
    <div class="tbl tblWd">
      <table>
        <thead>
          <xsl:call-template name="tblHeaders"/>
        </thead>
        <tbody>
          <xsl:for-each select="$fares">
            <xsl:call-template name="Fares" />
          </xsl:for-each>
        </tbody>
      </table>
    </div>
    <!-- close table -->
  </xsl:for-each>
</xsl:template>
0
 
LVL 60

Expert Comment

by:Geert Bormans
ID: 24397476
you can drop the key, you don't need it

For the rest it is hard to have an opinion without knowing the named templates
and without knowing what $airlineDisp exactly is

Can you show me the definition of $airlineDisp?
0
 

Author Comment

by:d1114170
ID: 24402048
$airlineDisp is Offers/Continent/Country/Fare[Airline=$airline]
were $airline is the variable airline that is passed in.
0
 
LVL 60

Expert Comment

by:Geert Bormans
ID: 24402454
OK, I still ca't see where you call for the template airlineFares,
the
  <xsl:apply-templates select="Fare[airline = $airline]"/>
can only work in the context of a Country, so it will not work here, because you are in the context of a Continent
because of:   <xsl:for-each select="Continent">
Drop that line, it doesn't do anything here, and was suggested without me seeing your source first

I think your code more or less works, but it doesn' group by continent,
for each continent it gives the full fare list back, that has the $airline Airline
In order to group per continent, you will need this
- store the CID of the continent in a variable
- use that variable in a predicate in $fares
since you create $fares at the beginning, you can be selective there
  <xsl:variable name="fares" select="$airlineDisp[ancestor::Continent/CID = current()/CID]" />


0
 
LVL 60

Expert Comment

by:Geert Bormans
ID: 24402462
If this works for you, that would mean we are on the right track, let me know then, because this selection is something I would do using keys
0
 
LVL 60

Expert Comment

by:Geert Bormans
ID: 24402536
Here is a little test programm that shows you how to use a key as an index in this project
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>
    <xsl:param name="airline">Delta</xsl:param>
    <xsl:key name="fare-by-airline-and-CID" match="Fare" use="concat(ancestor::Continent/CID, Airline)"/>
    <xsl:template match="Offers">
        <xsl:for-each select="Continent">
            <xsl:variable name="this-cid" select="CID"/>
            <xsl:variable name="fares" select="key('fare-by-airline-and-CID', concat($this-cid, $airline))"/>
            <CONTINENT cid="{CID}">
                <xsl:copy-of select="$fares"/>
            </CONTINENT>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

Open in new window

0
 

Author Comment

by:d1114170
ID: 24405859
Hi Gertone,

That is working well thank you.
The only issue left is that it still creates a table even though their may not be any records to display. ideally i need it to only display the continent table if there are any flights in that continent with that airline.

many thanks
<xsl:template name="airlineFares">
    <xsl:for-each select="Continent">
    <xsl:variable name="this-cid" select="CID"/>
    <xsl:variable name="fares" select="key('fare-by-airline-and-CID', concat($this-cid, $airline))"/>
    <CONTINENT cid="{CID}">
        <h2>
          <xsl:call-template name="Title">
            <xsl:with-param name="cid" select="CID"/>
          </xsl:call-template>
        </h2>
        <div class="tbl tblWd">
          <table>
            <thead>
              <xsl:call-template name="tblHeaders"/>
            </thead>
            <tbody>
              <xsl:choose>
                <xsl:when test="$order='descending'">
                  <xsl:for-each select="$fares">
                    <xsl:sort select="(*|*/*)[name()=$sortID]" order="descending"/>
                    <xsl:call-template name="Fares"/>
                  </xsl:for-each>
                </xsl:when>
                <xsl:otherwise>
                  <xsl:for-each select="$fares">
                    <xsl:sort select="(*|*/*)[name()=$sortID]"/>
                    <xsl:call-template name="Fares"/>
                  </xsl:for-each>
                </xsl:otherwise>
              </xsl:choose>
            </tbody>
          </table>
        </div>
        <!-- close table -->
        </CONTINENT>
        </xsl:for-each>
  </xsl:template>

Open in new window

0
 
LVL 60

Accepted Solution

by:
Geert Bormans earned 2000 total points
ID: 24407550
You could add a test
    <xsl:template name="airlineFares">
        <xsl:for-each select="Continent">
            <xsl:variable name="this-cid" select="CID"/>
            <xsl:variable name="fares" select="key('fare-by-airline-and-CID', concat($this-cid, $airline))"/>
            <xsl:if test="$fares">
                <CONTINENT cid="{CID}">
                    <h2>
                        <xsl:call-template name="Title">
                            <xsl:with-param name="cid" select="CID"/>
                        </xsl:call-template>
                    </h2>
                    <div class="tbl tblWd">
                        <table>
                            <thead>
                                <xsl:call-template name="tblHeaders"/>
                            </thead>
                            <tbody>
                                <xsl:choose>
                                    <xsl:when test="$order='descending'">
                                        <xsl:for-each select="$fares">
                                            <xsl:sort select="(*|*/*)[name()=$sortID]" order="descending"/>
                                            <xsl:call-template name="Fares"/>
                                        </xsl:for-each>
                                    </xsl:when>
                                    <xsl:otherwise>
                                        <xsl:for-each select="$fares">
                                            <xsl:sort select="(*|*/*)[name()=$sortID]"/>
                                            <xsl:call-template name="Fares"/>
                                        </xsl:for-each>
                                    </xsl:otherwise>
                                </xsl:choose>
                            </tbody>
                        </table>
                    </div>
                    <!-- close table -->
                </CONTINENT>
            </xsl:if>
        </xsl:for-each>
    </xsl:template>

Open in new window

0
 

Author Comment

by:d1114170
ID: 24410475
hi, gertone,
I have started a new thread that I feel is linked to this so maybe would be easier if you helped me?!

Its called 'hide and show looped tables xsl and javascript'

cheers
0
 
LVL 60

Expert Comment

by:Geert Bormans
ID: 24466768
I saw that one is gone,
I saw there is a new one... if you need a quote, you can send me an email (see profile)
cheers
0

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

JavaScript has plenty of pieces of code people often just copy/paste from somewhere but never quite fully understand. Self-Executing functions are just one good example that I'll try to demystify here.
Originally, this post was published on Monitis Blog, you can check it here . In business circles, we sometimes hear that today is the “age of the customer.” And so it is. Thanks to the enormous advances over the past few years in consumer techno…
Viewers will learn about the regular for loop in Java and how to use it. Definition: Break the for loop down into 3 parts: Syntax when using for loops: Example using a for loop:
The viewer will learn how to create a basic form using some HTML5 and PHP for later processing. Set up your basic HTML file. Open your form tag and set the method and action attributes.: (CODE) Set up your first few inputs one for the name and …
Suggested Courses

741 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question