?
Solved

help grouping xml results

Posted on 2009-05-15
13
Medium Priority
?
254 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
  • 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
The new generation of project management tools

With monday.com’s project management tool, you can see what everyone on your team is working in a single glance. Its intuitive dashboards are customizable, so you can create systems that work for you.

 

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

The new generation of project management tools

With monday.com’s project management tool, you can see what everyone on your team is working in a single glance. Its intuitive dashboards are customizable, so you can create systems that work for you.

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.
This article demonstrates how to create a simple responsive confirmation dialog with Ok and Cancel buttons using HTML, CSS, jQuery and Promises
Viewers will learn about if statements in Java and their use The if statement: The condition required to create an if statement: Variations of if statements: An example using if statements:
The viewer will receive an overview of the basics of CSS showing inline styles. In the head tags set up your style tags: (CODE) Reference the nav tag and set your properties.: (CODE) Set the reference for the UL element and styles for it to ensu…
Suggested Courses

601 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