Solved

help grouping xml results

Posted on 2009-05-15
13
239 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
DevOps Toolchain Recommendations

Read this Gartner Research Note and discover how your IT organization can automate and optimize DevOps processes using a toolchain architecture.

 
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

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
JS Plugin 4 29
Google Sheets Script 21 51
Creating a dynamic URL - set dates to upcoming weekend 6 30
Master Content Pages, WebForms, and Session Variables 1 29
Browsers only know CSS so your awesome SASS code needs to be translated into normal CSS. Here I'll try to explain what you should aim for in order to take full advantage of SASS.
Nothing in an HTTP request can be trusted, including HTTP headers and form data.  A form token is a tool that can be used to guard against request forgeries (CSRF).  This article shows an improved approach to form tokens, making it more difficult to…
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 the learn the benefit of plain text editors and code an HTML5 based template for use in further tutorials.

929 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

8 Experts available now in Live!

Get 1:1 Help Now