You are here:  » Getting two sets of data from one XML file

Support Forum



Getting two sets of data from one XML file

Submitted by globalguide on Tue, 2008-02-05 22:03 in

I'm a bit unclear how to use MagicParser to extract all the node ids, lat and long from this:

http://api.openstreetmap.org/api/0.5/map?bbox=11.54,48.14,11.543,48.145

all the best

Scott

Submitted by support on Wed, 2008-02-06 08:01

Hi Scott,

Assuming that you're using auto-detection, what's happening here is that because there are more WAY records than NODE records, these are what are being picked up as the repeating record. To handle this, you need to specify a format string in order to specify that it is the NODE records you want. In the case of your XML, the format string required is:

xml|OSM/NODE/

Here's an example, which will display each node ID, lat and long:

<?php
  
require("MagicParser.php");
  function 
myRecordHandler($record)
  {
    print 
"<p>";
    print 
"Node ID: ".$record["NODE-ID"]." ";
    print 
"Lat: ".$record["NODE-LAT"]." ";
    print 
"Lon: ".$record["NODE-LON"]." ";
    print 
"</p>";
  }
  
$url "http://api.openstreetmap.org/api/0.5/map?bbox=11.54,48.14,11.543,48.145";
  
MagicParser_parse($url,"myRecordHandler","xml|OSM/NODE/");
?>

If you want to access the other set of records in that file (WAYs), then the format string would be:

xml|OSM/WAY/

Hope this helps!
Cheers,
David.

Submitted by globalguide on Wed, 2008-02-06 10:16

Thanks very much David. It worked like a dream!

You must get fed up with all the questions but now I'm having a problem with WAY from the same file.

WAY is in this format:

<way id="4020271" visible="true" timestamp="2007-07-13T09:52:50+01:00" user="user_4133">
  <nd ref="21324374" />
  <nd ref="21324376" />
  <nd ref="398692" />
  <tag k="highway" v="secondary" />
  <tag k="created_by" v="JOSM" />
  <tag k="name" v="Arnulfstraße" />
  <tag k="lanes" v="2" />
  <tag k="oneway" v="true" />
</way>

I need to parse the file so that the nd refs and the tag k elements are connected to the correct way ID.

So in one parse I need to pick up each nd ref, each tag k (both "highway" and "secondary" and the way id holding them. Is this straightforward?

all the best (again!)

Scott

Submitted by support on Wed, 2008-02-06 10:30

Hi Scott,

These are slightly trickier because there are multiple NDs and TAGs within each WAY record. Magic Parser resolves duplicate names by appending @2, @3 etc. to each field name, so some mechanism is required to reformat the data into a more usable format.

The best method in this case I think is to loop through $record, checking for NDs, and the -K and -V attributes of each TAG. You do this by using a foreach() loop through $record; and then adding each value you come across (using string comparison) to an appropriate array - $nds for the NDs and $tags for the TAGs. It's probably easier to show you by example, so here's a script to create arrays of each:

View Output

<?php
  header
("Content-Type: text/plain");
  require(
"MagicParser.php");
  function 
myRecordHandler($record)
  {
    
$nds = array();
    
$tags = array();
    foreach(
$record as $k => $v)
    {
      if (
strpos($k,"-REF"))
      {
        
$nds[] = $v;
      }
      if (
strpos($k,"-K"))
      {
        
$currentK $v;
      }
      if (
strpos($k,"-V") && $currentK)
      {
        
$tags[$currentK] = $v;
        
$currentK "";
      }
    }
    
print_r($nds);
    
print_r($tags);
    print 
"\n\n";
  }
  
$url "http://api.openstreetmap.org/api/0.5/map?bbox=11.54,48.14,11.543,48.145";
  
MagicParser_parse($url,"myRecordHandler","xml|OSM/WAY/");
?>

This script using content-type text/plain for clarity, but in your application this is probably not relevant, and you can then just use the data from $nds and $tags as required.

$nds is just an array of the nd refs, whereas $tags is an associative array using the -K and -V attributes from the XML, so you would access the "lanes" value as:

$tags["lanes"]

Hope this helps!
Cheers,
David.

Submitted by globalguide on Wed, 2008-02-06 11:21

Hi David,

Sorry for all these questions. I implemented this like so:

function XMLtrails_passtwo($item)
{
    $nds = array();
    $tags = array();
    foreach($item as $k => $v)
    {
      if (strpos($k,"-REF"))
      {
        $nds[] = $v;
      }
      if (strpos($k,"-K"))
      {
        $currentK = $v;
      }
      if (strpos($k,"-V") && $currentK)
      {
        $tags[$currentK] = $v;
        $currentK = "";
      }
    }
    echo $nds[1]."<br>";
    echo $tags["highway"]."<br>";
}
   require("MagicParser.php");
   $url = "http://api.openstreetmap.org/api/0.5/map?bbox=11.54,48.14,11.543,48.145";
   $format_string = "xml|OSM/WAY/";
   MagicParser_parse($url, "XMLtrails_passtwo", $format_string);

It parsed the very first WAY successfully, but then gave up.

best regards

Scott

Submitted by support on Wed, 2008-02-06 11:28

Hi Scott,

I just ran your code on my server, completely unmodified and it has displayed 5 WAYs correctly..

View Output

Are you only seeing:

21324376
secondary

...when you run this on your server?

Cheers,
David.

Submitted by globalguide on Wed, 2008-02-06 12:02

It works perfect - I confused myself by using item[1] hardcoded. Now solved with a count variable inside the foreach and resolving that way.

Thanks for all of your excellent help!

Scott