[PHP] XML parser geeft involledige data terug

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • koraks243
  • Registratie: Oktober 2003
  • Niet online

koraks243

Last quoth the raven...

Topicstarter
Ik hoop dat ik met het openen van dit topic niet teveel regeltjes overtreed. Mocht dat wel zo zijn, excuus. Ik kom zelf niet zoveel in P&W, dus heb niet zoveel kaas gegeten van de lokale mores ;) Ik heb overigens de search gebruikt en ook op de rest van het net gezocht, maar ik kan niks vinden wat hier verband mee kan houden. Maar dat kan natuurlijk ook te maken hebben met de grote hoeveelheid info over de combo PHP + XML die beschikbaar is.

Korte omschrijving van de situatie
Ik heb een PHP scriptje dat een XML file (afkomstig uit een Progress database, hier heb ik verder geen details over; ik krijg de files kant en klaar aangeleverd) moet parsen om er uiteindelijk SQL inserts van te maken. Meestal werkt het script prima, maar bij sommige XML-elementen gaat het mis: de parser geeft dan niet alle PCDATA uit een element door aan mijn pc_data_handler.

De werkwijze
Voor het parsen van de XML files gebruik ik de standaard PHP XML functies. Ik heb begrepen dat er meerdere parsers beschikbaar zijn, maar ik zal het met deze moeten doen, aangezien het script bij een externe provider moet draaien. Hieronder volgen de regels die de parser aanmaken (let op: dit gebeurt in een class!):

PHP:
1
2
3
4
5
//Create an XML parser
$this->xml_parser = xml_parser_create();
xml_set_object($this->xml_parser, $this);
xml_set_element_handler($this->xml_parser, "_xml_start_element_handler", "_xml_end_element_handler");
xml_set_character_data_handler($this->xml_parser, "_xml_character_data_handler");

Het probleem doet zich uitsluitend voor bij het verkrijgen van PCDATA, dus ik zal hieronder alleen de code van de character data handler invoegen:
PHP:
1
2
3
4
5
function _xml_character_data_handler ($parser, $data) {
  if ($this->import_element) {
    $this->records[$this->num_records][$this->current_field] = mysql_escape_string($data);
  }
}


Het probleem
Wat gebeurt er nu? Wel, in 99,9% van de gevallen krijgt de character data handler de gegevens aangeleverd van de parser zoals ze ook letterlijk in de XML file staan. Heel soms, maar wel steeds bij dezelfde records, krijg ik echter maar een gedeelte van de data die in het element staan. Van de waarde "1234" krijg ik bijvoorbeeld alleen maar "34" of "123". Uiteraard vermoedde ik dat het moest liggen aan de XML, dus heb ik, bij wijze van test, een record in de XML file wat steeds problemen gaf ('record A'), omgewisseld met een record op een andere locatie binnen dezelfde file ('record B'). Na die omwisseling, geeft ineens 'record B' de problemen die eerst voorkwamen bij 'record A', terwijl 'record A' gewoon goed wordt geparst. Hieronder volgt een voorbeeldje van een record wat geparst moet worden:
XML:
1
2
3
4
5
6
<Record>
  <id-postco>956</id-postco>
  <post-code>1234 AB</post-code>
  <straat>Stationsstraat</straat>
  <id-woonpl>10</id-woonpl>
</Record>


Zoals gezegd, heb ik geen verband kunnen vinden tussen de XML data en de vermoedelijke fout in de parser. Iemand enig idee wat hier aan de hand is? Excuseer als het iets heel triviaals is, maar ik raak er echt geen wijs meer uit...

This is the way the world ends. Not with a bang but a whimper. -T.S. Eliot


Acties:
  • 0 Henk 'm!

  • twanvl
  • Registratie: Februari 2005
  • Laatst online: 22-08 11:42
Dit klinkt als iets dat er boven staat, voor record A, en voor record B als je ze omwisselt.

Acties:
  • 0 Henk 'm!

  • koraks243
  • Registratie: Oktober 2003
  • Niet online

koraks243

Last quoth the raven...

Topicstarter
Lijkt me stug, het is een bestandje van 100 records en ze zijn allemaal structureel hetzelfde. De data zijn natuurlijk anders, maar het is overal gewoon netjes ascii, geen rare tekens, alle element-tags netjes afgesloten enzo.

This is the way the world ends. Not with a bang but a whimper. -T.S. Eliot


Acties:
  • 0 Henk 'm!

  • Onno
  • Registratie: Juni 1999
  • Niet online
koraks schreef op zondag 24 april 2005 @ 18:51:
Het probleem doet zich uitsluitend voor bij het verkrijgen van PCDATA, dus ik zal hieronder alleen de code van de character data handler invoegen:
PHP:
1
2
3
4
5
function _xml_character_data_handler ($parser, $data) {
  if ($this->import_element) {
    $this->records[$this->num_records][$this->current_field] = mysql_escape_string($data);
  }
}
Zoals ook in de documentatie staat mag je er niet vanuit gaan dat alle data in een keer doorgegeven wordt. Deze handler kan per element een willekeurig aantal keren aangeroepen worden. Je moet per keer de data dus toevoegen aan wat je al had uit eerdere calls.

Acties:
  • 0 Henk 'm!

  • koraks243
  • Registratie: Oktober 2003
  • Niet online

koraks243

Last quoth the raven...

Topicstarter
Ok dan, dat is iig een nuttige hint. Maar hoe ondervang je dan dat van '1234' bv. alleen maar '34' wordt teruggegeven? Ik weet vantevoren nl. niet of ie data aan het begin van het element of aan het eind weg zal laten.

Edit: Bovenstaand probleem treedt in praktijk gelukkig niet op. Ik heb de code van de character data handler veranderd in:
PHP:
1
2
3
4
5
function _xml_character_data_handler ($parser, $data) {
  if ($this->import_element) {
    $this->records[$this->num_records][$this->current_field] .= mysql_escape_string($data);
  }
}

Nu werkt het prima, de paar fouten die ik eerst kreeg, zijn er nu uit!

Onno, enorm bedankt!

/me slaps himself for not reading the manual....again ;)

[ Voor 56% gewijzigd door koraks243 op 24-04-2005 19:33 ]

This is the way the world ends. Not with a bang but a whimper. -T.S. Eliot