Page 1 of 1

changing a sample code

Posted: Wed Oct 06, 2004 3:43 pm
by grudz
Hi everybody,

I was wondering if anybody can help me out. I consider myself an intermediate php programmer, I do know enough to build a website, but what i don't know (so far) is functions and arrays (i've always built sites where they do not need them)

Anyway, I found a sample script that parses xml into php but i really can't figure out how to change it to how i want it.

Anyway, take a look at my code, it'll be easier that way

Code: Select all

$compiled_langs = array(); 
$interprt_langs = array(); 
$flag = ''; 
$count = 0; 

function opening_element($parser, $element, $attributes) { 
    // opening XML element callback function 

    global $flag; 

    if ($element == 'languages') 
        $flag = $attributes['type']; 

} 

function closing_element($parser, $element) { 
    // closing XML element callback function 

    global $flag; 

    if ($element == 'languages') 
        $flag = ''; 
} 

function character_data($parser, $data) { 
    // callback function for character data 

    global $flag; 

    if ($flag == 'compiled') { 
        global $compiled_langs; 
        $compiled_langs[] = $data; 
    } 

    if ($flag == 'interpreted') { 
        global $interprt_langs; 
        $interprt_langs[] = $data; 
    } 

} 

$parser = xml_parser_create(); 
xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, false); 
xml_set_element_handler($parser, 'opening_element', 'closing_element'); 
xml_set_character_data_handler($parser, 'character_data'); 

$document = file('http://www.di.fm/partners/xml/playlists.xml'); 

foreach ($document as $line) { 
    xml_parse($parser, $line); 
} 

xml_parser_free($parser); 

printf("The following compiled languages were found...\n"); 
foreach ($compiled_langs as $name) { 
    $count++; 
    printf("%' 3d. %s\n", $count, $name); 
} 

$count = 0; 
printf("\nThe following interpreted languages were found...\n"); 
foreach ($interprt_langs as $name) { 
    $count++; 
    printf("%' 3d. %s\n", $count, $name); 
}
as you can see http://www.di.fm/partners/xml/playlists.xml that's the xml page i am using, all i want on my php page is to show this:

Channel: Vocal Trance
Track: (whatever the track is)

Vocal Trance is the first channel on that list, it's the only one i need with the first track.

thank you

Posted: Wed Oct 06, 2004 3:59 pm
by feyd
although I haven't worked with the xml functions, I'd guess that changing the internals of character_data() to look for 'channel' or 'channeltitle', and 'tracktitle' would basically work.

what you can do is add some debugging print statements within each of the functions to echo out their arguments on each call.

Posted: Wed Oct 06, 2004 5:03 pm
by Christopher
You have picked a difficult task. I would recommend using the DOM XML functions unless you really want a crash course in PHP.

The opening_element() function deals with starting tags like your <STATIONTITLE> tag. The closing_element() function deals with starting tags like your </STATIONTITLE> tag. The character_data() function deals with the stuff between the tags like your "Digitally Imported Radio".

You need to add your own handler functions for each tag. Here is the idea:

Code: Select all

$handlers = array(
    'STATIONTITLE' => 'station_title_handler',
}

function station_title_handler($attributes) { 
// check attributes, deal with a stack, set state, etc. here
} 

// opening XML element callback function 
function opening_element($parser, $element, $attributes) { 
    global $handlers; 

    if (is_callable($handlers[$element])) {
        ${$handlers[$element]} ($attribute);
    }
}
If you really want to do this I think I have a class around somewhere I can send to you.

Posted: Wed Oct 06, 2004 5:22 pm
by grudz
i do know php, the only thing i have trouble with is functions and arrays.....everything else is ok

Posted: Wed Oct 06, 2004 5:25 pm
by feyd
functions and arrays are probably 80+% of php. :?

Posted: Wed Oct 06, 2004 5:37 pm
by grudz
anything you can send to help me out arborint would be great, do you want me email address?

Posted: Wed Oct 06, 2004 6:09 pm
by feyd
adding some debugging like I suggested earlier:

Code: Select all

var_export(array(__LINE__=>func_get_args()));
resulted in:

Code: Select all

:snip:

array (
  11 =&gt; 
  array (
    0 =&gt; NULL,
    1 =&gt; 'CHANNELTITLE',
    2 =&gt; 
    array (
    ),
  ),
)

array (
  34 =&gt; 
  array (
    0 =&gt; NULL,
    1 =&gt; 'VocalTrance',
  ),
)

array (
  23 =&gt; 
  array (
    0 =&gt; NULL,
    1 =&gt; 'CHANNELTITLE',
  ),
)

:snip:
So it looks like you change opening_element() and closing_element() to look for the tags you want (swap 'language' for the tag(s) you want to look for.) I'd suggest using [php_man]strcasecmp[/php_man]() to do the comparison. Then change character_data() to record to whichever array you want to have channeltitles and whatnot...

Posted: Thu Oct 07, 2004 2:04 am
by timvw
it looks like the snippet i've put on http://home.mysth.be/~timvw/programming/php/service.txt but it was only a quick-n-dirty solution to parse simple xml like http://home.mysth.be/~timvw/programming/php/sample.txt, as in only one level of repeating nodes.

You could expand the snippet to parse the xml, but in that case you are doing more or less the same as [php_man]domxml[/php_man] was built for.

Another solution could be using[php_man]xslt[/php_man] and grab/translate /CHANNELS/CHANNEL[0]/TRACK/TRACK[0] from your original xml.

Posted: Thu Oct 07, 2004 2:36 am
by twigletmac
This is precisely the sort of task that XSLT is nicely suited for, plus it's much more fun to work with...

Mac