You are here:  » XML parse question


XML parse question

Submitted by goran on Thu, 2010-03-25 14:57 in

Hi all

Perhaps this question does not belong in this forum, but still ...

I am a newbie at PHP and have a problem I can not solve.
I have searched the forum and other PHP pages, but have not found any solution.
Mostly because I do not really understand how PHP works.

I get a xml file from my weather program that looks like this.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<DATA>
 <PROGRAM NAME="LogTemp">
  <VERSION>2.24.0.92</VERSION>
 </PROGRAM>
 <TEMPERATURES>
 <SENSOR ROMID="24000000B63E9D26-T">
  <VALUE>1.84</VALUE>
 </SENSOR>
 <SENSOR ROMID="4A00080189FF2310">
  <VALUE>12.00</VALUE>
 </SENSOR>
 <SENSOR ROMID="A4000000B6539126-T">
  <VALUE>6.31</VALUE>
 </SENSOR>
 <SENSOR ROMID="5400080124ECF710">
  <VALUE>7.63</VALUE>
 </SENSOR>
 </TEMPERATURES>
 <HUMIDITY>
 <SENSOR ROMID="EA000000B64E8626-H">
  <VALUE>40.49</VALUE>
 </SENSOR>
 <SENSOR ROMID="A4000000B6539126-H">
  <VALUE>72.10</VALUE>
 </SENSOR>
 <SENSOR ROMID="57000000A8F7C526-H">
  <VALUE>44.23</VALUE>
 </SENSOR>
 </HUMIDITY>
 <SOLAR_RADIATION>
 <SENSOR ROMID="24000000B63E9D26-S">
  <VALUE>12.20</VALUE>
 </SENSOR>
 </SOLAR_RADIATION>
</DATA>

When I use Magic Parser with the following script:

<?php
  
require("MagicParser.php");
  
$filename "last.xml";
  
$format_string MagicParser_getFormat($filename);
  if (!
$format_string)
  {
    print 
"<p>".MagicParser_getErrorMessage()."</p>";
    exit;
  }
  function 
myRecordHandler($record)
  {
    print 
"<table border='1'>";
    foreach(
$record as $key => $value)
    {
      print 
"<tr>";
      print 
"<td align='left'>".$key."</td>";
      print 
"<td>".htmlentities($value)."&nbsp;</td>";
      print 
"</tr>";
    }
    print 
"</table>";
    
// return a non-zero value to stop reading any more records
    
return 0;
  }
  
MagicParser_parse("last.xml","myRecordHandler","xml|DATA/");
?>

The result is a two column table like this:

DATA
PROGRAM
PROGRAM-NAME LogTemp
PROGRAM/VERSION 2.24.0.92
TEMPERATURES
TEMPERATURES/SENSOR
TEMPERATURES/SENSOR-ROMID 24000000B63E9D26-T
TEMPERATURES/SENSOR/VALUE 1.22
TEMPERATURES/SENSOR@1
TEMPERATURES/SENSOR@1-ROMID 4A00080189FF2310
TEMPERATURES/SENSOR/VALUE@1 12.00
TEMPERATURES/SENSOR@2
TEMPERATURES/SENSOR@2-ROMID A4000000B6539126-T
TEMPERATURES/SENSOR/VALUE@2 6.22
TEMPERATURES/SENSOR@3
TEMPERATURES/SENSOR@3-ROMID 5400080124ECF710
TEMPERATURES/SENSOR/VALUE@3 7.63
HUMIDITY
HUMIDITY/SENSOR
HUMIDITY/SENSOR-ROMID EA000000B64E8626-H
HUMIDITY/SENSOR/VALUE 40.49
HUMIDITY/SENSOR@1
HUMIDITY/SENSOR@1-ROMID A4000000B6539126-H
HUMIDITY/SENSOR/VALUE@1 74.85
HUMIDITY/SENSOR@2
HUMIDITY/SENSOR@2-ROMID 57000000A8F7C526-H
HUMIDITY/SENSOR/VALUE@2 44.62
SOLAR_RADIATION
SOLAR_RADIATION/SENSOR
SOLAR_RADIATION/SENSOR-ROMID 24000000B63E9D26-S
SOLAR_RADIATION/SENSOR/VALUE 5.57

My question is, how can I get this table with only the "SENSOR/VALUE" values in the table?
I also wish that each value has its own name.

I hope someone can help me solve this.

Regards
Göran

Submitted by support on Thu, 2010-03-25 15:46

Hello Göran,

You can make the foreach loop only display fields with SENSOR/VALUE in the $key like this:

    foreach($record as $key => $value)
    {
      if (strpos($key,"SENSOR/VALUE")!==FALSE)
      {
        print "<tr>";
        print "<td align='left'>".$key."</td>";
        print "<td>".htmlentities($value)."&nbsp;</td>";
        print "</tr>";
      }
    }

However, you might want to know a bit more about what each value is from the other data, so if that's not quite what you want, let me know and we can add more information to the table.

Hope this helps!
Cheers,
David.

Submitted by goran on Thu, 2010-03-25 22:16

Hi David
And thanks for your fast response and help.

Now I have my table with the measuring values to the right.
But I also want to give each value their own names on the left side,
instead of the text that is there now. For example, "Basement" or "Workshop".

To complicate it, it should also be a unit description to the right of the value reading.
Like "°C" and "%"

Regards
Göran

Submitted by support on Thu, 2010-03-25 22:25

Hello Göran,

Looking at the output from your data, does the ROMID value that precedes each SENSOR/VALUE correspond to a label such as your examples "Basement" or "Workshop".

What you could do is create a look-up array, and then store the last ROMID seen, and use it to display the friendly label, for example:

<?php
  
require("MagicParser.php");
  
$filename "last.xml";
  
$labels["24000000B63E9D26-T"] = "Basement";
  
$labels["4A00080189FF2310"] = "Workshop";
  
// etc.
  
function myRecordHandler($record)
  {
    global 
$labels;
    print 
"<table border='1'>";
    foreach(
$record as $key => $value)
    {
      if (
strpos($key,"ROMID")!==FALSE)
      {
        
$romid $value;
      }
      if (
strpos($key,"SENSOR/VALUE")!==FALSE)
      {
        print 
"<tr>";
        print 
"<td align='left'>".$labels[$romid]."</td>";
        print 
"<td>".htmlentities($value)."&nbsp;</td>";
        print 
"</tr>";
      }
    }
    print 
"</table>";
    
// return a non-zero value to stop reading any more records
    
return 0;
  }
  
MagicParser_parse("last.xml","myRecordHandler","xml|DATA/");
?>

So as this stands, the left column will be empty for any ROMID that you have not entered a friendly label for, but you can add these to the $labels array to display all the names you need!

Hope this helps!
All the best,
David.

Submitted by goran on Fri, 2010-03-26 13:03

Hi David

WOW! What great support!

I wish I had your skills in php.
I will try to learn the basics of php.

Now I have only one problem left with this table.

Is it possible to show a unit value to the right of each measured reading.
Like "°C" and "%", as you se below.

Temp i solen 14.56   °C
Temp Verkstad 12.19   °C
Temp Krypgrund 7.44   °C
Temp Gaststuga 9.31   °C
Hum Verkstad 42.42   %
Hum Krypgrund 76.31   %
Hum Gaststuga 37.77   %
Solar Radiation 69.32   %

Regards
Göran

Submitted by support on Fri, 2010-03-26 13:14

Hello Göran,

For sure - try something like this:

<?php
  
require("MagicParser.php");
  
$filename "last.xml";
  
$labels["24000000B63E9D26-T"] = "Basement";
  
$labels["4A00080189FF2310"] = "Workshop";
  
// etc.
  
function myRecordHandler($record)
  {
    global 
$labels;
    print 
"<table border='1'>";
    foreach(
$record as $key => $value)
    {
      if (
strpos($key,"TEMPERATURES")!==FALSE)
      {
        
$label "Temp";
        
$units "°C";
      }
      if (
strpos($key,"HUMIDITY")!==FALSE)
      {
        
$label "Hum";
        
$units "%";
      }
      if (
strpos($key,"SOLAR_RADIATION")!==FALSE)
      {
        
$label "Solar Radiation";
        
$units "%";
      }
      if (
strpos($key,"ROMID")!==FALSE)
      {
        
$romid $value;
      }
      if (
strpos($key,"SENSOR/VALUE")!==FALSE)
      {
        print 
"<tr>";
        print 
"<td align='left'>".$labels[$romid]."</td>";
        print 
"<td>".$label."&nbsp;".htmlentities($value)."&nbsp;".$units."</td>";
        print 
"</tr>";
      }
    }
    print 
"</table>";
    
// return a non-zero value to stop reading any more records
    
return 0;
  }
  
MagicParser_parse("last.xml","myRecordHandler","xml|DATA/");
?>

Hope this helps!
Cheers,
David.

Submitted by goran on Fri, 2010-03-26 14:01

David!

Thank you so very much for your great help.

Now is the table just as I want it.

I wish you a nice weekend.

Best regards
Goran