Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: Xmldocument get values


This question is not answered. Helpful answers available: 2. Correct answers available: 1.


Permlink Replies: 2 - Last Post: Jan 8, 2018 1:52 PM Last Post By: Andrew Hodson
Andrew Hodson

Posts: 39
Registered: 8/23/10
Xmldocument get values  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 8, 2018 11:58 AM
I have an xml document from openweather that looks like this:

<weatherdata>
- <location>
<name>Hastings</name>
<type />
<country>NZ</country>
<timezone />
<location altitude="0" latitude="-39.6381" longitude="176.8492" geobase="geonames" geobaseid="2190224" />
</location>
<credit />
- <meta>
<lastupdate />
<calctime>0.0036</calctime>
<nextupdate />
</meta>
<sun rise="2018-01-07T16:54:29" set="2018-01-08T07:43:21" />
- <forecast>
- <time from="2018-01-08T00:00:00" to="2018-01-08T03:00:00">
<symbol number="800" name="clear sky" var="01d" />
<precipitation />
<windDirection deg="47.0005" code="NE" name="NorthEast" />
<windSpeed mps="5.21" name="Gentle Breeze" />
<temperature unit="celsius" value="21.27" min="21.27" max="21.27" />
<pressure unit="hPa" value="1022.33" />
<humidity value="83" unit="%" />
<clouds value="clear sky" all="0" unit="%" />
</time>
- <time from="2018-01-08T03:00:00" to="2018-01-08T06:00:00">
<symbol number="801" name="few clouds" var="02d" />
<precipitation />
<windDirection deg="46.0001" code="NE" name="NorthEast" />
<windSpeed mps="6.06" name="Moderate breeze" />
<temperature unit="celsius" value="21.14" min="21.14" max="21.14" />
<pressure unit="hPa" value="1021.71" />
<humidity value="78" unit="%" />
<clouds value="few clouds" all="12" unit="%" />
</time>
i have successfully loaded into a txmldocument. i can traverse nodes like this:

OuterRoot := LDocument.DocumentElement;
for i := 0 to OuterRoot.ChildNodes.Count -1 do
begin
Memo1.Lines.Add(OuterRoot.ChildNodes[i].NodeName);
if OuterRoot.ChildNodes[i].NodeName='forecast' then
begin
Memo1.Lines.Add(OuterRoot.ChildNodes[i].NodeName +':'+OuterRoot.ChildNodes[i].xml);
EntryNode := OuterRoot.ChildNodes[i];
for j := 0 to EntryNode.ChildNodes.Count -1 do
begin
LowerNode:=Entrynode.ChildNodes[j] ;
for k := 0 to LowerNode.ChildNodes.Count -1 do
begin
Memo1.Lines.Add( LowerNode.ChildNodes[k].NodeName + '-' + LowerNode.ChildNodes[k].Prefix);
end;
end;

end;
end;

How do i get the values from the LowerNode.ChildNodes. For example I want to get the forecast temperature value from <temperature unit="celsius" value="21.27" min="21.27" max="21.27" />

I have tried all sorts of methods but none work. Would appreciate any help you can give
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Xmldocument get values  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 8, 2018 1:32 PM   in response to: Andrew Hodson in response to: Andrew Hodson
Andrew Hodson wrote:

How do i get the values from the LowerNode.ChildNodes. For example I
want to get the forecast temperature value from <temperature
unit="celsius" value="21.27" min="21.27" max="21.27" />

You already know how to locate a node by name. Your EntryNode is
pointing at the <forecast> element, and your LowerNode is pointing at
the <time> elements. So, you just need to loop through the <time>
element's child nodes looking for <temperature> elements, and then you
can read their attributes.

Try something more like this:

var
  WeatherDataNode, ForecastNode, EntryNode, TemperatureNode: IXMLNode;
  TemperatureValue: string;
begin
  ...
  WeatherDataNode := LDocument.DocumentElement;
  ForecastNode := WeatherDataNode.ChildNodes.FindNode('forecast');
  if ForecastNode <> nil then
  begin
    EntryNode := ForecastNode.ChildNodes.First;
    while EntryNode <> nil do
    begin
      if EntryNode.NodeName = 'time' then
      begin
        TemperatureNode := EntryNode.ChildNodes.FindNode('temperature');
        if TemperatureNode <> nil then
        begin
          TemperatureValue := TemperatureNode.Attributes['value'];
          // use value as needed...
        end;
      end;
      EntryNode := EntryNode.NextSibling;
    end;
  end;
  ...
end;


Alternatively, consider using a XPath query instead, for example:

var
  WeatherDataNode: IXMLNode;
  intfSelect: IDomNodeSelect;
  dnResult: IDomNodeList;
  I: Integer;
  TemperatureValue: string;
begin
  WeatherDataNode := LDocument.DocumentElement;
  if Supports(WeatherDataNode.DOMNode, IDomNodeSelect, intfSelect) then
  begin
    dnResult :=
intfSelect.selectNodes('/weatherdata/forecast/time/temperature/@value');
    if dnResult <> nil then
    begin
      for i := 0 to dnResult.length-1 do
      begin
        TemperatureValue := dnResult[i].nodeValue;
        // use value as needed...
      end;
    end;
  end else
  begin
    // use code shown further above...
  end;
end;


--
Remy Lebeau (TeamB)
Andrew Hodson

Posts: 39
Registered: 8/23/10
Re: Xmldocument get values  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 8, 2018 1:52 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Remy Lebeau (TeamB) wrote:
Andrew Hodson wrote:

How do i get the values from the LowerNode.ChildNodes. For example I
want to get the forecast temperature value from <temperature
unit="celsius" value="21.27" min="21.27" max="21.27" />

You already know how to locate a node by name. Your EntryNode is
pointing at the <forecast> element, and your LowerNode is pointing at
the <time> elements. So, you just need to loop through the <time>
element's child nodes looking for <temperature> elements, and then you
can read their attributes.

Try something more like this:

var
  WeatherDataNode, ForecastNode, EntryNode, TemperatureNode: IXMLNode;
  TemperatureValue: string;
begin
  ...
  WeatherDataNode := LDocument.DocumentElement;
  ForecastNode := WeatherDataNode.ChildNodes.FindNode('forecast');
  if ForecastNode <> nil then
  begin
    EntryNode := ForecastNode.ChildNodes.First;
    while EntryNode <> nil do
    begin
      if EntryNode.NodeName = 'time' then
      begin
        TemperatureNode := EntryNode.ChildNodes.FindNode('temperature');
        if TemperatureNode <> nil then
        begin
          TemperatureValue := TemperatureNode.Attributes['value'];
          // use value as needed...
        end;
      end;
      EntryNode := EntryNode.NextSibling;
    end;
  end;
  ...
end;


Alternatively, consider using a XPath query instead, for example:

var
  WeatherDataNode: IXMLNode;
  intfSelect: IDomNodeSelect;
  dnResult: IDomNodeList;
  I: Integer;
  TemperatureValue: string;
begin
  WeatherDataNode := LDocument.DocumentElement;
  if Supports(WeatherDataNode.DOMNode, IDomNodeSelect, intfSelect) then
  begin
    dnResult :=
intfSelect.selectNodes('/weatherdata/forecast/time/temperature/@value');
    if dnResult <> nil then
    begin
      for i := 0 to dnResult.length-1 do
      begin
        TemperatureValue := dnResult[i].nodeValue;
        // use value as needed...
      end;
    end;
  end else
  begin
    // use code shown further above...
  end;
end;


--
Remy Lebeau (TeamB)

Perfect thankyou.Works greats
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02