Improve company productivity with a Business Account.Sign Up

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 256
  • Last Modified:

help grouping xml results

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
d1114170
Asked:
d1114170
  • 8
  • 5
1 Solution
 
Geert BormansInformation ArchitectCommented:
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
 
Geert BormansInformation ArchitectCommented:
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
 
d1114170Author Commented:
here is the xml.
xml.txt
0
Upgrade your Question Security!

Your question, your audience. Choose who sees your identity—and your question—with question security.

 
d1114170Author Commented:
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
 
Geert BormansInformation ArchitectCommented:
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
 
d1114170Author Commented:
$airlineDisp is Offers/Continent/Country/Fare[Airline=$airline]
were $airline is the variable airline that is passed in.
0
 
Geert BormansInformation ArchitectCommented:
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
 
Geert BormansInformation ArchitectCommented:
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
 
Geert BormansInformation ArchitectCommented:
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
 
d1114170Author Commented:
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
 
Geert BormansInformation ArchitectCommented:
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
 
d1114170Author Commented:
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
 
Geert BormansInformation ArchitectCommented:
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
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

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.

  • 8
  • 5
Tackle projects and never again get stuck behind a technical roadblock.
Join Now