Link to home
Start Free TrialLog in
Avatar of shawnsouthern
shawnsouthern

asked on

XML Filtering for WebApp using Visual Studio

I am working on a WebApp in Visual Studio 2008, that will pull information from an XML file and display the information(date, time, temperatue and humidity). I am using a Datalist control to bind that data, using an XPath expression. The problem I am having is that when run I have empty nodes returned, I would like to filter the data to only return the current information (from the past hour). The problem is that the XML file is pulled from Environment Canada and some of the nodes have the same names so I can't seem to find a way to filter them properly. I have included my code, sample of output and the XML file I am drawing from.
Thanks
<asp:DataList 
        ID="DataList1" 
        runat="server" 
        DataSourceID="XmlDataSource1">
        
            <ItemTemplate>
             <table cellpadding="4" cellspacing="4">
              <tr>
               <td style="vertical-align:top; width:120">
                   Date (mm/dd/yyyy):<asp:Label ID="MonthLabel" Text='<%# XPath("dateTime/month") %>' runat="server"/>
                <asp:Label ID="DayLabel" Text='<%# XPath("dateTime/day") %>' runat="server"/>
                <asp:Label ID="YearLabel" Text='<%# XPath("dateTime/year") %>' runat="server"/>
                   ,<br />
                   Time:<br />
                <asp:Label ID="HourLabel" Text='<%# XPath("dateTime/hour") %>' runat="server"/>
                <asp:Label ID="MinuteLabel" Text='<%# XPath("dateTime/minute") %>' runat="server"/>
                
                <asp:Label ID="TemperatureLabel" Text='<%# XPath("temperature") %>' runat="server"/>
                <asp:Label ID="HumidityLabel" Text='<%# XPath("relativeHumidity") %>' runat="server"/>

Open in new window

Untitled.jpg
Untitled2.jpg
Avatar of Bob Learned
Bob Learned
Flag of United States of America image

1) You can attach the real XML file to this question.

2) XPath("temperature") will only work if 'temperature' is a top-level node, otherwise you need '//temperature', or a fully-qualfied path like this example:

      /node1/node1.1/node1.1.1
Avatar of shawnsouthern
shawnsouthern

ASKER

XML File
I am not able to attch the xml file because it is not in the list of accepted extensions
Rename the file, and change the extension to .txt.
I was just playing around with your XML file, and an XmlDataSource, with different XPath and XPathSelect expressions, and I came up with this.  It was just my way of understanding your XML hierarchy better.

It is not quite what you need, but I don't exactly understand what you are looking to filter.  
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Weather Example</title>
</head>
<body>
    <form id="form1" runat="server">
        <asp:DataList ID="HeaderDataList" runat="server" DataSourceID="XmlDataSource1" Font-Names="Trebuchet MS"
            Font-Size="Small">
            <ItemTemplate>
                <table cellpadding="0" cellspacing="0">
                    <tr>
                        <td style="vertical-align: top; width: 200px">
                            <asp:Label ID="DateLabel" runat="server" Text="Date (mm/dd/yyyy):" ForeColor="SteelBlue"
                                Font-Bold="True" />
                        </td>
                        <td style="vertical-align: top; width: 100px">
                            <asp:Label ID="DateValue" Text='<%# XPath("//forecastGroup/dateTime/month") + "." + XPath("//forecastGroup/dateTime/day") + "." + XPath("//forecastGroup/dateTime/year") %>'
                                runat="server" />
                        </td>
                        <tr>
                            <td>
                                <asp:Label ID="TimeLabel" runat="server" Text="Time (hh:mm):" ForeColor="SteelBlue"
                                    Font-Bold="true" />
                            </td>
                            <td>
                                <asp:Label ID="TimeValue" Text='<%# XPath("//forecastGroup/dateTime/hour") + ":" + XPath("//forecastGroup/dateTime/minute") %>'
                                    runat="server" />
                            </td>
                        </tr>
                        <tr>
                            <td>
                                <br />
                            </td>
                        </tr>
                    </tr>
                    <tr>
                        <td>
                            <asp:GridView ID="ForecastGridView" runat="server" DataSource='<%# XPathSelect("//forecastGroup/forecast") %>'
                                Font-Names="Trebuchet MS" Font-Size="Small" AutoGenerateColumns="false">
                                <AlternatingRowStyle BackColor="beige" />
                                <Columns>
                                    <asp:TemplateField HeaderText="Period:">
                                        <ItemTemplate>
                                            <asp:Label ID="PeriodText" Text='<%# XPath("period") %>' runat="server" />
                                        </ItemTemplate>
                                    </asp:TemplateField>
                                    <asp:TemplateField HeaderText="Temperature (C):">
                                        <ItemTemplate>
                                            <asp:Label ID="TemperatureValue" Text='<%# XPath("temperatures/temperature") %>'
                                                runat="server" />
                                        </ItemTemplate>
                                    </asp:TemplateField>
                                    <asp:TemplateField HeaderText="Humidity (%):">
                                        <ItemTemplate>
                                            <asp:Label ID="HumidityValue" Text='<%# XPath("relativeHumidity") %>' runat="server" />
                                        </ItemTemplate>
                                    </asp:TemplateField>
                                </Columns>
                            </asp:GridView>
                        </td>
                    </tr>
                </table>
            </ItemTemplate>
        </asp:DataList>
        <asp:XmlDataSource ID="XmlDataSource1" runat="server" DataFile="~/s0000329-e---Copy.xml"
            XPath="//forecastGroup"></asp:XmlDataSource>
    </form>
</body>
</html>

Open in new window

I am eventually going to pull the current temperature and humidity so that I will be able to calculate and display the current HUmidex reading. Along with the Date and time of the reading. This is going to be a part of our companies Heat Stress Plan and the Humidex reading needs to be avaiable on SharePoint
>>I am eventually going to pull the current temperature and humidity
Can you describe that means from the XML file hierarchy?
Environment Canada updates the information hourly, so from the Current conditions for the current date and hour I would like to pull the temperature and humidity. Because in this XML file there is a forecast temperate/humidity for the day and for the next week, and I would like to filter these readings out as only the most recent readings are useful.
How can you tell what is "most recent"?
say it is 7:45 than the 7:00 reading would be the most acurate, since it is recorded every hour the reading from that hour would be the most up to date
I see <forecastGroup>, which has a time, and then 6 <forecast> elements under that one.  The <forecastGroup> is the only one that I see with a time, and there is only one instance.  Is this a complete XML file, or a fragment?  Will there be multiple <forecastGroup> elements?
This is the complete XML file. I am not sure what you mean by multiple <forcastGroup> elements as I am looking for the time of the current conditions. The first few nodes of the file are dealing with time and under the <currentconditions> there is all of the following information:
 <currentConditions>
 <station code="yxu" lat="43.02N" lon="81.15W">London Int'l Airport</station>
 <dateTime name="observation" zone="UTC" UTCOffset="0">
 <year>2008</year>
 <month name="July">07</month>
 <day name="Wednesday">02</day>
 <hour>17</hour>
 <minute>00</minute>
 <timeStamp>20080702170000</timeStamp>
 <textSummary>Wednesday July 02, 2008 at 17:00 UTC</textSummary>
 </dateTime>

I think the text Summary of the timestamp may be the most effective means of filtering out information
It looks like you only have one <currentConditions> element, so why do you need a DataList?
I am new to this so I was following a tutorial to start and they used either a datalist or a treeview, and I thought a datalist would be more appropriate. Is there another data form that would make this easier?
I would think that a light-weight Repeater might be a faster choice, but you are right, since you need to data-bind the control to the XmlDataSource.

If you only have a single element, then why would you need to filter?
Before when I tried using the exact path to the current conditions information I was getting nothing returned. The paths I used above was the only way to have data displayed, and I need to filter because many of them are under  <date/time>  and my question was how to sort out the ones a I don't want when they are the same node names.
I am not exactly sure how to filter.  I would think that you would have to read in the XML, look for the node that told you current time, and then programmatically set the XmlDataSource filter.
Which leads me back to my original question :

"The problem is that the XML file is pulled from Environment Canada and some of the nodes have the same names so I can't seem to find a way to filter them properly"
I am soooo confused.  <currentConditions> is one element, and has time that is UTC and one that is EDT, but that is it--where does the filtering need to be applied?
As I mentioned before using the long node path which included the <currentconditions> did not return anything for me.. The only way data was returned was to use the broad <dateTime> node
Do you want these values from <currentConditions>?
<currentConditions>
  <station code="yxu" lat="43.02N" lon="81.15W">London Int'l Airport</station> 
- <dateTime name="observation" zone="UTC" UTCOffset="0">
  <year>2008</year> 
  <month name="July">07</month> 
  <day name="Wednesday">02</day> 
  <hour>17</hour> 
  <minute>00</minute> 
  <timeStamp>20080702170000</timeStamp> 
  <textSummary>Wednesday July 02, 2008 at 17:00 UTC</textSummary> 
  </dateTime>
- <dateTime name="observation" zone="EDT" UTCOffset="-4">
  <year>2008</year> 
  <month name="July">07</month> 
  <day name="Wednesday">02</day> 
  <hour>13</hour> 
  <minute>00</minute> 
  <timeStamp>20080702130000</timeStamp> 
  <textSummary>Wednesday July 02, 2008 at 13:00 EDT</textSummary> 
  </dateTime>
  <condition>Partly Cloudy</condition> 
  <temperature unitType="metric" units="C">25.8</temperature> 
  <dewpoint unitType="metric" units="C">15.0</dewpoint> 
  <humidex unitType="metric">30</humidex> 
  <pressure unitType="metric" units="kPa" change="0.06" tendency="falling">101.2</pressure> 
  <visibility unitType="metric" units="km">24.1</visibility> 
  <relativeHumidity units="%">51</relativeHumidity> 
- <wind>
  <speed unitType="metric" units="km/h">30</speed> 
  <gust unitType="metric" units="km/h" /> 
  <direction>SW</direction> 
  <bearing units="degrees">220</bearing> 
  </wind>
  </currentConditions>

Open in new window

yes...
Then, I am confused what you really need.  You should be able to set the filter to //currentConditions, and go from there.
I don't know how to set a filter... I worked with a tutoiral to get this far and needed help with the filtering...that is what my whole question is... how do I filter?? If it is simply the node path to filte, then that isn't working for me because I already tried that and got a blank screen for output. I just started with VB a few months ago and have had no formal training, I have been using tutorials and text books at my job.
ASKER CERTIFIED SOLUTION
Avatar of Bob Learned
Bob Learned
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
OMG thank you so much for all of your help. That was a lot of trouble for something so small..it isn't returning the time value, but that is something small that I can fiddle with. I am not sure if you will knw this either but is it possible to now grab those values and perform a calculation on them?
I need to calculate the Humidex factor given the information, since EC only gives that info when it is over 26 C and the health and safety committe would like the humidex reading always available to them on SharePoint.
You can do similar processing in code:


Imports System.Xml
 
Partial Class _Default
    Inherits Page
 
    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Dim document As XmlDocument = Me.XmlDataSource1.GetXmlDocument()
 
        Dim currentConditionsNode As XmlNode = document.SelectSingleNode("//currentConditions")
 
        Dim monthNode As XmlNode = currentConditionsNode.SelectSingleNode("dateTime/month")
        Dim dayNode As XmlNode = currentConditionsNode.SelectSingleNode("dateTime/day")
        Dim yearNode As XmlNode = currentConditionsNode.SelectSingleNode("dateTime/year")
 
        Dim hourNode As XmlNode = currentConditionsNode.SelectSingleNode("dateTime/hour")
        Dim minuteNode As XmlNode = currentConditionsNode.SelectSingleNode("dateTime/minute")
 
        Dim conditionNode As XmlNode = currentConditionsNode.SelectSingleNode("condition")
        Dim temperatureNode As XmlNode = currentConditionsNode.SelectSingleNode("temperature")
        Dim relativeHumidityNode As XmlNode = currentConditionsNode.SelectSingleNode("relativeHumidity")
 
        Dim currentDate As Date = New Date(yearNode.InnerText, monthNode.InnerText, dayNode.InnerText)
        Dim time As TimeSpan = New TimeSpan(hourNode.InnerText, minuteNode.InnerText, 0)
        Dim condition As String = conditionNode.InnerText
        Dim temperature As Decimal = temperatureNode.InnerText
        Dim relativeHumidity As Decimal = relativeHumidityNode.InnerText
    End Sub
 
End Class

Open in new window

Again thank you for all of your help and patience
Thank you!!!