none
XSLT sort problem

    Question

  • I have an XML file containing TV listings that I am trying to process with XSLT to produce a customized report of my favorite programs.  The XML is much more sophisticated than the textbook examples and the examples I've found on the web.  It contains a default namespace and is structured like a relational database.  I am having trouble sorting the listings by their air date.

    To get the air date I must first follow the xtvd/program/program path to get the id attribute, then match that value to the program attribute in the xtvd/schedules/schedule path to get the air date.  (There may be more than one air date for a single program.) 

    The sort I coded sorts the air dates just fine for the same program that airs on more than one date, but what I want is all the data related to a program from all related nodes sorted along with the schedule node.  Essentially what I'm after is a nicely formatted report of the sort you might find in TV Guide, but containing only those programs I'm interested in.

    Here's what my code looks like and a very abbreviated sample of the XML.  If anyone can help I'd appreciate it.

    <?xml version="1.0" encoding="UTF-8" ?>

    <xsl:stylesheet version="1.0"

    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"

    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

    xmlns:xsd="http://www.w3.org/2001/XMLSchema"

    xmlns:ms="urn:schemas-microsoft-com:xslt"

    xmlns:dt="urn:schemas-microsoft-com:datatypes"

    xmlns:ld="http://example.com/2006/ld"

    xmlns:df="urn:TMSWebServices">

    <ms:script implements-prefix="ld" language="C#">

    <![CDATA[

    public string formatDate (string xsdDateTime, string format)

    {

    DateTime local = XmlConvert.ToDateTime(xsdDateTime, XmlDateTimeSerializationMode.Local);

    return local.ToString(format);

    }

    ]]>

    </ms:script>

    <xsl:output method="xml" omit-xml-declaration="no"

    doctype-system="http://www.w3c.org/TR/xhtml1/DTD/xhtml1-strict.dtd"

    doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN" />

    <xsl:key name="progid" match="df:programs/df:program" use="@id" />

    <xsl:key name="crew" match="df:productionCrew/df:crew" use="@program"/>

    <xsl:key name="genre" match="df:genres/df:programGenre" use="@program"/>

    <xsl:key name="schprogid" match="df:schedules/df:schedule" use="@program" />

    <xsl:key name="lineupstationid" match="df:lineups/*/df:map" use="@station"/>

    <xsl:key name="stationid" match="df:stations/df:station" use="@id"/>

    <xsl:key name="prt" match="df:schedule" use="@program"/>

    <xsl:param name = "pmtr"/>

    <xsl:template match="/">

    <html xmlns ="http://www.w3.org/1999/xhtml">

    <head>

    <title>TV Listings</title>

    </head>

    <body>

    <h1>

    TV Data from: <xsl:value-of select="ld:formatDate(//@from, 'g')"/>

    to: <xsl:value-of select="ld:formatDate(//@to, 'g')"/>

    </h1>

    <xsl:for-each select="$pmtr">

    <p></p>Title: <xsl:value-of select="df:title"/>

    SubTitle: <xsl:value-of select="df:subtitle" /><br/>

    Description: <xsl:value-of select="df:description" /><br/>

    Series: <xsl:value-of select="df:series" />

    RunTime: <xsl:value-of select="df:runTime" />

    MPAA Rating: <xsl:value-of select="df:mpaaRating" />

    Star Rating: <xsl:value-of select="df:starRating" />

    Year: <xsl:value-of select="df:year" />

    ShowType: <xsl:value-of select="df:showType" />

    Color Code: <xsl:value-of select="df:colorCode" />

    Syndicated Episode Number: <xsl:value-of select="df:syndicatedEpisodeNumer" />

    Advisory: <xsl:value-of select="df:advisory" />

    OriginalAirDate:

    <xsl:value-of select="ms:format-date(df:originalAirDate,MMMdyy,'en-US')"/>

    <!-- Not interested in this data

    <xsl:for-each select="key('crew', @id)">

    <xsl:for-each select=".//df:member">

    Role: <xsl:value-of select="df:role"/>

    GivenName: <xsl:value-of select="df:givenname"/>

    SurName: <xsl:value-of select="df:surname"/>

    </xsl:for-each>

    </xsl:for-each>

    <xsl:for-each select="key('genre', @id)">

    <xsl:for-each select=".//df:genre">

    Class: <xsl:value-of select="df:class"/>

    Relevance: <xsl:value-of select="df:relevance"/>

    </xsl:for-each>

    </xsl:for-each>

    -->

    <xsl:for-each select="key('schprogid', @id)">

    <xsl:sort select ="@time" data-type="text" order="ascending"/>

    Date: <xsl:value-of select="ld:formatDate(@time, 'g')"/>

    Duration:

    Hours:<xsl:value-of select="substring(@duration,3,2)"/>

    Minutes:<xsl:value-of select="substring(@duration,6,2)"/>

    Repeat: <xsl:value-of select="@repeat"/>

    <!-- Not interested in this data

    TVRating: <xsl:value-of select="@tvRating"/>

    Stereo: <xsl:value-of select="@stereo"/>

    HDTV: <xsl:value-of select="@repeat"/>

    Subtitled: <xsl:value-of select="@subtitled"/>

    CloseCaptioned: <xsl:value-of select="@closeCaptioned"/>

    Dolby: <xsl:value-of select="@dolby"/>

    -->

    </xsl:for-each>

    <xsl:for-each select="df:part">

    Part <xsl:value-of select="@number"/>

    of <xsl:value-of select="@total"/>

    </xsl:for-each>

    <xsl:for-each select="key('stationid', @station)">

    CallSign: <xsl:value-of select="df:callSign"/>

    <!-- Not interested in this data

    Name: <xsl:value-of select="df:name"/>

    Affiliate: <xsl:value-of select="df:affiliate"/>

    -->

    </xsl:for-each>

    <xsl:for-each select="key('lineupstationid', @station)">

    Channel: <xsl:value-of select="@channel"/>

    </xsl:for-each>

    </xsl:for-each>

    </body>

    </html>

    </xsl:template>

    </xsl:stylesheet>

      Part of the XML File:

    <?xml version="1.0" ?>

    - <xtvd xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" from="2006-12-27T23:30:10Z" to="2007-01-03T23:30:10Z" xmlns="urn:TMSWebServices">
    - <stations>
    - <station id="10436">
      <callSign>KERA</callSign>
      <name>KERA</name>
      <affiliate>PBS Affiliate</affiliate>
      </station>
    - <station id="10830">
      <callSign>KXAS</callSign>
      <name>KXAS</name>
      <affiliate>NBC Affiliate</affiliate>
      </station>
    - <station id="16123">
      <callSign>TVLAND</callSign>
      <name>TV Land</name>
      <affiliate>Satellite</affiliate>
      </station>
    - <station id="11430">
      <callSign>WFAA</callSign>
      <name>WFAA</name>
      <affiliate>ABC Affiliate</affiliate>
      </station>
      </stations>
    - <lineups>
    - <lineup id="TX42457:-" name="Time Warner Cable" location="Commerce" type="Cable" postalCode="75428">
      <map station="10436" channel="13" />
      <map station="10830" channel="5" />
      <map station="11430" channel="8" />
      <map station="16123" channel="44" from="2004-12-06" />
      </lineup>
      </lineups>
    - <schedules>
      <schedule program="EP0441070199" station="10436" time="2006-12-27T23:30:00Z" duration="PT00H30M" tvRating="TV-Y" stereo="true" closeCaptioned="true" />
    <schedule program="EP7079270104" station="10436" time="2007-01-02T07:30:00Z" duration="PT00H30M" stereo="true" closeCaptioned="true" /> <schedule program="EP7079270104" station="10436" time="2007-01-02T07:30:00Z" duration="PT00H30M" stereo="true" closeCaptioned="true" />
      <schedule program="EP7079270104" station="10436" time="2006-12-30T01:00:00Z" duration="PT00H30M" stereo="true" closeCaptioned="true" />
     </schedules>
    <programs>
    <program id="EP7079270104">
      <title>NOW</title>
      <description>Imprisoned for three years in Afghanistan and Guantanamo Bay, Cuba, Moazzam Begg's story alleges kidnapping, torture and murder.</description>
      <showType>Series</showType>
      <series>SH707927</series>
      <originalAirDate>2006-12-29</originalAirDate>
      </program>
    - <program id="EP7086960044">
      <title>Everyday Food</title>
      <subtitle>Time-Saving Recipes</subtitle>
      <description>Rib-eye with garlic-thyme marinade and baked polenta fries; eggplant-ricotta bake; tortellini with mushroom sauce; almond torte.</description>
      <showType>Series</showType>
      <series>SH708696</series>
      <originalAirDate>2006-12-21</originalAirDate>
      </program>
    </programs>
    </xtvd>
    Thursday, January 04, 2007 10:27 PM

Answers

  • Perhaps I was too harsh in my comment about dignity and respect.  I apologize.  However it seems that you an I simply cannot communicate effectively.  Should I decide to make another post to this forum please refrain from responding.
    Saturday, January 06, 2007 2:25 PM

All replies

  • There are many problems with the provided  code, I will just show a few of them:

    1. TV Data from: <xsl:value-of select="ld:formatDate(//@from, 'g')"/>

        to: <xsl:value-of select="ld:formatDate(//@to, 'g')"/>

    //@from selects the set of all attributes named "from" anywhere in the xml document (in the provided xml document there are two such attributes). This is probably not what you wanted.

    //@to -- the same remark applies.

    2. <xsl:for-each select="$pmtr">

    The xsl:param named "pmtr" is undefined

     

    A very important observation is that you have not yet provided a sample of the desired output to be produced from the provided xml file.

    Therefore, it is not possible to guess what that desired output could be.

     

    Cheers,
    Dimitre Novatchev

    Thursday, January 04, 2007 11:40 PM
  • Thanks for being so courteous and patient in your response.  I guess my general statement of a report requirment of TV listing data is not obvious so I'll try again.

    Regarding your response number 1:  There is only 1 occurance of the "from" and "to" attributes in the entire XML file.  They occur at the root node.  I guess it would speed up processing if I included a path to them, however.

    As far as your response number 2 goes:  in a previous thread that you said was too long, someone told me how to pass parameters to the XSLT code from my C# program that executes the XSLT code.  Here is the entirety of the C# code and it works quite well.

    // Create the XsltArgumentList.

    XsltArgumentList argList = new XsltArgumentList();

    string program = "Sewing With Nancy";

    program = "//df:programs/df:program[df:title='Sewing With Nancy']" +

    "|//df:programs/df:program[df:title='Green Acres']" +

    "|//df:programs/df:program[df:title='NOW']";

    XPathDocument document = new XPathDocument(@"..\..\zap2itxml.xml");

    XPathNavigator navigator = document.CreateNavigator();

    XPath"df", "urn:TMSWebServices");

    "pmtr", "", nodes);

    XsltSettings XSLSettings = new XsltSettings(false,true);

    XslCompiledTransform ct = new XslCompiledTransform();

    ct.Load(@"..\..\tvTransform.xslt", XSLSettings, new XmlUrlResolver());

    XmlWriterSettings settings = new XmlWriterSettings();

    settings.ConformanceLevel = ConformanceLevel.Fragment;

     

    XmlWriter writer = XmlWriter.Create(@"..\..\TVSchedule.html", settings);

    ct.Transform(@"..\..\zap2itxml.xml", argList, writer);

    writer.Close();

    Finally, as to what I want the report to look like:  I've not finished the HTML coding to make the format look nice (I can do that myself), but here's some of the HTML output from the program.  You will see from the following that for program title "NOW" (which is the same program but airs twice) that the airing dates are in sorted order for that program, but the overall listing of programs is not in chronological order.  I want an HTML file output from my XSLT/C# program that will list all shows in chronological order and for those shows like "NOW" where the same episode airs more than once to be listed in their entirety (with all the detail for the program -- title, subtitle, description, etc.) twice (once for each air date).  As you can see from the output below all the detail data for the NOW program is listed only once followed by the two air dates.  This is not how it would appear if you were to look at TV listings at www.titantv.com or all the other TV listing services.  All the detail data would be repeated at the second, or third, or fourth airing and would be sorted in chronological order along with all the other programs.

    TV Data from: 12/27/2006 5:30 PM to: 1/3/2007 5:30 PM

    Title: Sewing With Nancy SubTitle: Fancy Footworks
    Description: Using the open toe foot, the fringe foot, the multicord foot and the edge joining foot.
    Series: SH003790 RunTime: MPAA Rating: Star Rating: Year: ShowType: Series Color Code: Syndicated Episode Number: Advisory: OriginalAirDate: 11/19/2006 Date: 12/29/2006 1:30 PM Duration: Hours:00 Minutes:30 Repeat:

    Title: NOW SubTitle:
    Description: Imprisoned for three years in Afghanistan and Guantanamo Bay, Cuba, Moazzam Begg's story alleges kidnapping, torture and murder.
    Series: SH707927 RunTime: MPAA Rating: Star Rating: Year: ShowType: Series Color Code: Syndicated Episode Number: Advisory: OriginalAirDate: 12/29/2006 Date: 12/29/2006 7:00 PM Duration: Hours:00 Minutes:30 Repeat: Date: 1/2/2007 1:30 AM Duration: Hours:00 Minutes:30 Repeat:

    Title: Green Acres SubTitle: The Special Delivery Letter
    Description: Oliver tries to track down a special-delivery letter.
    Series: SH001952 RunTime: MPAA Rating: Star Rating: Year: ShowType: Series Color Code: Syndicated Episode Number: Advisory: OriginalAirDate: 11/22/1969 Date: 12/28/2006 4:00 AM Duration: Hours:00 Minutes:30 Repeat:

    Friday, January 05, 2007 3:43 PM
  •  perstam wrote:

    Thanks for being so courteous and patient in your response.  I guess my general statement of a report requirment of TV listing data is not obvious so I'll try again.

    Regarding your response number 1:  There is only 1 occurance of the "from" and "to" attributes in the entire XML file.  They occur at the root node.  I guess it would speed up processing if I included a path to them, however.

    Not true: there are two different occurences of the "from" attribute in the provided xml document: at the top node and also at this element:

    <map station="16123" channel="44" from="2004-12-06" />

     

    Cheers,
    Dimitre Novatchev

    Friday, January 05, 2007 4:36 PM
  • OK, but your response simply states that I made an error in my post it does not offer any help in helping me to understand how to get the results I want.  Do I have to start another thread to get a proper answer?

    At any rate it is curious and I'm baffled as to why my code for the from attribute works as coded.

    Friday, January 05, 2007 5:33 PM
  • As to why you dont get the "help" you want, it seems the reason is that the problem is complex and not well defined.

    I have many years' experience and have helped many hundreds of people, when they are able to formulate well their problem.

    A well defined problem consists of a complete (but the minimal possible) example, including a xml document, an xslt transformation, the exact xml document (or html or text file) wanted as result of the transformation, the actual results that are produced, explanation what is wrong with the actual results.

    So, if you had just provided a source xml document, the exact results wanted and an explanation of the desired properties of the transformation, that would be sufficient for people to understand and help.

    At this time we have a source xml document (but with wrong statements about its attributes) and the exact results wanted are still not provided.

     

    Tip: Start with something as simple as possible -- try to extract the essence of your problem in the simplest possible example -- it will be much easier to formulate, understand and solve, and its solution will be directly applicable in the solution of the original problem.

    Failure to define precisely a problem is often indicative of not having a good understanding of what the problem is.

     

    Cheers,
    Dimitre Novatchev

    Friday, January 05, 2007 6:07 PM
  • OK, I'll try again. 
     
    I really thought everyone was familiar with TV listings, but I guess they are not.  And this forum software leaves a lot to be desired in the way it unpredictably formats what I type and paste in.  I just pasted the schema for the XML file and promptly got an error message and lost all the text I just typed in.  It would be nice to have an attach feature.  That way I could provide you with more complete information.  The XML file and its schema are way too large to paste into a post.
     
    The XML file contains detailed TV listing data for several days for every program that airs on every channel available on from my local cable TV provider.  Apparently the XML provider thought it necessary to structure the XML similar to a relational database because in order to find my favorite programs it is necessary to first start with the program title stored as the title element at this path /df:xtvd/df:programs/df:program ("df" is the name I had to make up for the default namespace that they chose to include in the XML data).  Once the desired program is found the "id" attribute must be saved to access the scheduled time of the program stored at path /df:xtvd/df:schedules/df:schedule.  The "id" attribute from the "program" element matches the "program" attribute from the "schedule" element.  Other similar relational database schemes are used throught the XML document, but I hope this gives you an idea of how the XML is structured since I am unable to paste the whole XML document nor its schema into this forum.
     
    I have managed to gather all the data items from the XML document for my favorite programs and have begun to format the HTML file that is output from the XSLT transform, but I have not been able to figure out how to sort this data in chronological order by air date/time.  The sort I've coded in the XSLT in my previous post sorts air date/times correctly if there's a program like NOW that airs more than once, but it does not sort the entire result of the transform.
     
    Simply put: I've extracted the data for my favorite programs.  What I can't seem to figure out is how to sort the data like a conventional TV listing would appear.  I want all my favorite programs sorted in the order of their air date/time and in the case of a program like NOW that airs multiple times for the program detail to be repeated in the output file each time it airs.
     
    As concisely as I can phrase this problem is:  the sort doesn't work right.
    Friday, January 05, 2007 7:50 PM
  • I still expect something like this example:

    XML (smallest possible that still helps demonstrate the problem. This is not the 4000 lines file I'll be really using, but this small file still demonstrates the problem):

    <programs>

      <program name="name1" air-time="time11"/>

      <program name="name2" air-time="time2"/>

    <!-- .......................................... -->

      <program name="nameN" air-time="timeN"/>

    </programs>

     

    My XSLT transformation (Smallest possible, non-problem related code removed (such as cosmetics/html), that demonstrates the problem):

     

    <xsl:stylesheet version="1.0"

     xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

     <xsl:output omit-xml-declaration="yes" indent="yes"/>

          <xsl:template match="programs">

            <programs>

              <xsl:for-each select="*">

                <xsl:sort select="@air-time"/>

               

                <xsl:copy-of select="."/>

              </xsl:for-each>

            </programs>

          </xsl:template>

    </xsl:stylesheet>

     

     

    The results I get (this is not the perfumed html version, but this still demonstrates the problem and is much simpler!):

     

    <programs>

      <program name="name1" air-time="time11" />

      <program name="name2" air-time="time2" />

      <program name="nameN" air-time="timeN" />

    </programs>

     

     

     

    But the results I want must be:

     

    <programs>

      <program name="name2" air-time="time2" />

      <program name="name1" air-time="time11" />

      <program name="nameN" air-time="timeN" />

    </programs>

     

    So, I actually want the "program" elements to be sorted by the numerical ending of their values, when these numerical endings are compared as numbers.

     

    End of example.

     

     

    Please, do note, that you can run the provided XSLT transformation on the provided XML document and you'd get exactly the reported result! (If you're not getting the reported result, then you just stop here, indicate my inaccuracy and do not waste your time further in trying to help me).

    Only when you can reproduce the problem precisely, then it makes sense to analyze it and to try to solve it.

     

    This is how people are reasoning when they approach a request for help in a technical forum.

     

    Is it clear now what is the structure of a request that will have the highest chances of receiving useful help?

     

    Cheers,
    Dimitre Novatchev

    Friday, January 05, 2007 9:39 PM
  • Hi Dimitri,

    Would you please update the email message in your profile?  Your current one doesn't work.

    Thanks.
    Friday, January 05, 2007 9:51 PM
  • I am very sorry to have to say this, but what is clear to me is that you are not interested in solving my problem nor are you interested in treating me with dignity and respect. 

    The code you placed in your last post is just like all the other examples I've found in textbooks and on the web -- way to simple.  As I've said before the XML file I'm trying to process is very complex.  That should be obvious if you read all my posts carefully.  Had my file been like one of those simple, ubiquitous "books" XML files that I find everywhere on the web I would never have had to come to this forum.

    Had you taken the time to closely examine my first post on this thread, I think you would realize that the sample code you just gave me doesn't come close to solving my problem nor does it provide an explanation as to what I'm doing wrong.  I came here hoping to learn something.  Providing just a code sample without an explanation is not helpful.

    I will have to look elsewhere for assistance in this problem.

    Friday, January 05, 2007 11:02 PM
  • I am also very sorry to say this, but until now I have been trying most sincerely to understand what was the problem!

    The sample of a good problem report took me more than one hour to write and I believe it truly shows what a good and consistent problem report should be.

    Any problem report (including yours) following the style and contents outlined, has very good chances of being quickly understood.

    Even in case you fail to embrace this style and structure of a problem report, I believe it will still be valuable to other readers of the forum.

    I am very sorry, but I still don't understand your problem.

    I cannot start writing a stylesheet that transforms the provided xml document to something not yet shown.

    I am still remaining interested to know what the problem is, so that I could then try to think about a solution.

    As for the alleged treatment wihout "dignity and respect", I have not used a single rude word and have been continuously explaining throughout this long thread that some necessary information is missing in the formulation of the problem. While mistreatment of respect and dignity are alleged, the truth is that I have only shown patience and good expectation.

    I believe that improving one's way of formulating problems to any technical forum will increase the chances of these problems being understood and solved.

    I am working in a company where our replies to customers in this and other forums are closely scrutinized and I always approach my replies in the most responsible way.

     

    Dimitre Novatchev

    Saturday, January 06, 2007 2:09 AM
  • Perhaps I was too harsh in my comment about dignity and respect.  I apologize.  However it seems that you an I simply cannot communicate effectively.  Should I decide to make another post to this forum please refrain from responding.
    Saturday, January 06, 2007 2:25 PM