Solved

help grouping xml results

Posted on 2009-05-15
13
238 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
 

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
Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

 
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 500 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

Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

Join & Write a Comment

Styling your websites can become very complex. Here I'll show how SASS can help you better organize, maintain and reuse your CSS code.
JavaScript can be used in a browser to change parts of a webpage dynamically. It begins with the following pattern: If condition W is true, do thing X to target Y after event Z. Below are some tips and tricks to help you get started with JavaScript …
The viewer will learn the benefit of using external CSS files and the relationship between class and ID selectors. Create your external css file by saving it as style.css then set up your style tags: (CODE) Reference the nav tag and set your prop…
The viewer will learn the basics of jQuery including how to code hide show and toggles. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery…

746 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

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now