Mario Enrico Ragucci: XML-Parser: zuviele Array-Einträge??

Hallo,

ich habe folgende Aufgabenstellung:

  • Auswertung einer XML-Datei nach Location eines Anrufers.

Die XML-Datei ist so aufgebaut:
<data>
<entity key="563019801" caption="Service call">
<group caption="R3">
<field key="C0" caption="Priority" type="Entity Reference" width="96pt" align="left">Priorität</field>
<field key="C1" caption="To deadline" type="Duration" width="95pt" align="right">DEADLINE</field>
<field key="C2" caption="Service  " type="String 80 (Text)" width="96pt" align="left">SERVICE</field>
<field key="C4" caption="Configuration Item Name:" type="String 255 (Description)" width="96pt" align="left">ITEM</field>
<field key="C5" caption="Open duration" type="Duration" width="96pt" align="right">DAUER</field>
<field key="C6" caption="Caller Location  " type="String 50 uppercase (Searchcode)" width="96pt" align="left">STANDORT</field>
<field key="C7" caption="Organization  " type="String 50 (Name)" width="96pt" align="left">Organisation</field>
</group></entity>

Meine PHP-Dateien sehen so aus:
libraries.inc.php
<?php

$duration  = array();
 $location  = array();
 $application         = array();
 $service  = array();
 $flag   = NULL;

function opening_element($parser, $element, $attributes)
 {
  global $flag;

if($element == 'field')
  {
   $flag = $attributes['caption'];
  }
 }

function closing_element($parser, $element)
 {
  if($element == 'field')
  {
   $flag = NULL;
  }
 }

function character_data($parser, $data)
 {
  global $flag;
  global $duration;
  global $location;
  global $application;
  global $service;

if($flag == 'Open duration')
  {
   $duration[] = $data;
  }
  if($flag == 'Configuration Item Name:')
  {
   $application[] = $data;
  }
  if($flag == 'Service  ')
  {
   $service[] = $data;
  }
  if($flag == 'Caller Location  ')
  {
   $location[] = $data;
  }
 }

?>

?>

index.php
<?php

$count  = 0;

require_once('libraries.inc.php');

$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('data.xml');

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

printf("Folgendes wurde gefunden: <br>");
 foreach($location as $item)
 {
  echo $item."<br>";
 }

?>

?>

Die Datei wird zwar geparsed, wenn ich aber als letzten Schritt in der foreach-Schleife zum Testen die Locations anzeigen lasse sind es statt 200 Einträgen plötzlich 400, und jeder zweite Eintrag im Array $service ist leer.

Sieht da jemand den Fehler? Ich leider nicht  :(

Danke im Voraus,

Mario

  1. Hi,

    Sieht da jemand den Fehler? Ich leider nicht  :(

    nur so eine Idee: doppelter Zeilenabstand durch unix ohne aber Leerzeilen im xml rauszuschmeissen?

    Gruesse, Joachim

    --
    Am Ende wird alles gut.
    1. Hi,

      Sieht da jemand den Fehler? Ich leider nicht  :(
      nur so eine Idee: doppelter Zeilenabstand durch unix ohne aber Leerzeilen im xml rauszuschmeissen?

      Gruesse, Joachim

      Hi zurück,

      nein, es lag tatsächlich an meiner eigenen Dummheit :(
      Habe in der Funktion "closing_element" vergessen, die Variable $flag als globale Variable zu deklarieren und hab's eben erst gemerkt...

      Trotzdem Danke für die Antwort!

      Gruß,
      Mario

      1. nein, es lag tatsächlich an meiner eigenen Dummheit :(
        Habe in der Funktion "closing_element" vergessen, die Variable $flag als globale Variable zu deklarieren und hab's eben erst gemerkt...

        der sax-parser sollte immer einen wohlgeformten datenstrom bekommen und nicht häppchenweise benutzt werden.
        daher solltest du die input-datei erst zu einem kompletten datenstrom zusammensetzen oder gleich den richtigen lesebefehl nehmen.

        aber das ganze sieht eh ein bischen abenteuerlich aus.

  2. Moin!

    Deine Auswertung scheint irgendwie zeilenweise vorzugehen. Das ist keine wirklich gute Idee.
    Ich verwende folgende (gefundene) Funktion:

    function xml2array($str) {
       $reg_exp = '/<(\w+)[^>]*>(.*?)</\1>/s';
       preg_match_all($reg_exp, $str, $match);
       foreach ($match[1] as $key=>$val) {
           if ( preg_match($reg_exp, $match[2][$key]) ) {
               $array[$val][] = xml2array($match[2][$key]);
           } else {
               $array[$val] = $match[2][$key];
           }
       }
       return $array;
    }

    $strFileName = "beispiel.xml";
    $FP = fopen($strFileName, "r") or die ("<div>Fataler Fehler: Datei $strFileName exitiert nicht oder Sie haben kein Leserecht.</div>");
    $arXML=xml2array(fread($FP, filesize($strFileName)));
    fclose($FP);

    MFFG (Mit freundlich- friedfertigem Grinsen)

    fastix®

    --
    Als Freiberufler bin ich immer auf der Suche nach Aufträgen: Schulungen, Development. Auch  für seriöse Agenturen.