Portal > Foren > PHP > PEAR, PECL und Frameworks > Bug im PEAR XML Parser?
Antwort
 
Themen-Optionen
Alt 13.02.2007, 19:43 Nach oben    #1
Erfahrener Benutzer
 
Registriert seit: 30.10.2005
Beiträge: 279
Standard Bug im PEAR XML Parser?

Hallo,

auf dem von mir gequälten Server ist php 4.3.4 installiert.
Ich muss eine XML Datei importieren. Allerdings bin ich dabei auf etwas gestoßen wo ich nicht weiter weiß.

In der Datei steht folgendes
<zeit>13 &amp; 15 Uhr</zeit>

Komischerweise hat das Parsen nie richtig hingehauen, bzw. mein Ergebnis Array war immer Abgetrennt. Bei einer direkten Ausgabe krieg ich folgendes:

falsch:
ZEIT: 13
ZEIT: &
ZEIT: 15 Uhr

richtig sollte sein:
ZEIT: 13 & 15 Uhr

In meinem Ergebnis Array bekomme ich nur 15 Uhr. Der vordere Teil vom String ist abgehakt. Soweit ich weiß ist das ein Bug oder ähnliches Jedenfalls sorgt dieser Entity &amp; für einen Umbruch, bzw. der Parser denkt es folgt ein weiterer gleicher Tag. Ich kann das &amp; auch nicht umwandeln in & da die XML File ja dann nicht mehr valid ist. Die Datei ist UTF-8

Also wie kann ich dieses Phänomen umgehen?
Ist es möglich weiterhin das mit dem PEAR XML Parser zu machen?
Oder sollte ich auf die internen XML Funktionen von PHP4 umsteigen, was zur Folge hätte das ich den Parser fast nochmal neu schreiben müsste.
Kann mir aber nicht vorstellen das es was hilft schließlich baut der PEAR XML Parser ja auf den PHP4 Funktionen auf.
ex³ ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 14.02.2007, 11:07 Nach oben    #2
Erfahrener Benutzer
 
Benutzerbild von JumperII
 
Registriert seit: 27.02.2006
Beiträge: 146
Standard

OK, geh drehe jetzt mal das Problem um, und lass die Frage nach dem Beispiel weg, obwohl es für die Problemlösung bei Dir dienlich wäre.

Der XML_Parser trennt die Daten (cdata) nach verschiedenen Gesichtspunkten, insbesondere nach seinen eigenen Scan-Algorithmus. Auf diese Weise ist er in der Lage, die Inhalte nach den vorgefertigten Schemen zu bearbeiten. Da gehören dazu: &-Codes, #-Codes und Zeilenvorschübe.

Für Dich heißt das, dass Du Deine Klasse so bauen musst, dass Du den Dateninhalt sauber zusammensetzen kannst. Wenn Du ein Beispiel dafür suchst, schau Dir Simple.php aus dem Paket an.

Gruß,
Jumper, the II.

Geändert von JumperII (14.02.2007 um 11:22 Uhr).
JumperII ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 14.02.2007, 11:49 Nach oben    #3
Erfahrener Benutzer
 
Benutzerbild von JumperII
 
Registriert seit: 27.02.2006
Beiträge: 146
Standard

So, damit Du eine Lösung siehst ....

File: 002.php
PHP-Code:
<?PHP
/**
 * example for XML_Parser_Simple
 *
 * @author      Stephan Schmidt <schst@php-tools.net>
 * @package     XML_Parser
 * @subpackage  Examples
 */

/**
 * require the parser
 */
require_once '../Parser.php';

class 
myParser extends XML_Parser
{

    var 
$sum_data;

    function 
myParser()
    {
        
parent::XML_Parser();
        
$this->sum_data = array();
        
$this->sum_data['current.id'] = '0';
    }

   
/**
    * handle start element
    *
    * @access   private
    * @param    resource    xml parser resource
    * @param    string      name of the element
    * @param    array       attributes
    */
    
function startHandler($xp$name$attribs)
    {
        
$new_id ""microtime() . "!" rand();
        
$parent_id $this->sum_data['current.id'];
        
$this->sum_data['current.id'] = $new_id;
        
$this->sum_data['data.' $this->sum_data['current.id'] . '.parentId'] = $parent_id;
        
$this->sum_data['data.' $this->sum_data['current.id'] . '.data'] = "";


//        printf('handle start tag: %s<br />'."\n", $name);
        
    
}

   
/**
    * handle start element
    *
    * @access   private
    * @param    resource    xml parser resource
    * @param    string      name of the element
    * @param    array       attributes
    */
    
function endHandler($xp$name)
    {
//        printf( 'handle data sum: %s<br />'."\n", $this->sum_data['data.'.$this->sum_data['current.id'].'.data']);
//        printf('handle end tag: %s<br />'."\n", $name);
        
        
printf'%s: %s'."\n"$name$this->sum_data['data.'.$this->sum_data['current.id'].'.data']);

        
$this->sum_data['current.id'] = $this->sum_data['data.'.$this->sum_data['current_id'].'.parentId'];
    }

    
/**
    * handle character data
    *
    * @access   private
    * @final
    * @param    resource    xml parser resource
    * @param    string      data
    */
    
function cdataHandler($xp$data)
    {
        
$olddata $this->sum_data['data.' $this->sum_data['current.id'] . '.data'];
        
$this->sum_data['data.' $this->sum_data['current.id'] . '.data'] =  $olddata $data;

//        printf( 'handle data: %s<br />'."\n", $data);
    
}
}

$p = &new myParser();

$result $p->setInputFile('001.xml');
$result $p->parse();
?>
File: 001.xml
Code:
<foo>
    <bar>content of bar</bar>
    <empty/>
    <argh foo="bar">test</argh>
    <zeit> 13 &amp; 15 Uhr </zeit>
</foo>
Ergebnis:
Code:
BAR: content of bar
EMPTY:
ARGH: test
ZEIT:  13 & 15 Uhr
FOO:
Gruß,
Jumper, the II.
JumperII ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 14.02.2007, 14:04 Nach oben    #4
Erfahrener Benutzer
 
Registriert seit: 30.10.2005
Beiträge: 279
Standard

Ja und jetzt? Ich krieg mein Array aus der Klasse so schon wie ich es brauche.

Problem ist das der Parser bei einem &amp; meint der Tag ist zuende und es folgt darauf ein weiteres Element vom gleichen Typ.

<zeit>13 &amp; 15 Uhr</zeit>

Der Parser meint es gäbe drei Elemente Zeit. Die Daten innerhalb des Tags werden in meinem Array gespeichert. Dadurch das er denkt es gibt 3 Elemente <Zeit> werden die vorherigen Daten des Zeit Elements überschrieben. In meinem Array steht dann [zeit] => 15 Uhr

Da stimmt doch was nicht das der Parser &amp; zum trennen benutzt.
ex³ ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 14.02.2007, 18:15 Nach oben    #5
Erfahrener Benutzer
 
Benutzerbild von JumperII
 
Registriert seit: 27.02.2006
Beiträge: 146
Standard

Falsch, wenn Du die Funktionalität des Parsers anders haben möchtest, musst Du ihn mit Deiner Erweiterung kapseln. Das ist alles. Im übrigen geht das Verhalten u.a. auf den guten alten SGML-Parser zurück.

Gruß,
Jumper, the II.
JumperII ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 14.02.2007, 20:01 Nach oben    #6
Erfahrener Benutzer
 
Registriert seit: 30.10.2005
Beiträge: 279
Standard

Also...

Das heißt es ist normal das der Parser bei einem &amp; so reagiert? Ich kann mir das irgendwie nicht vorstellen schließlich fängt ein <Element> so an und hört mit </Element> auf. Das das kfm. 'und' als entity einen ähnlichen Effekt erzielt verstehe ich nicht (erklärs mir).
ex³ ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 14.02.2007, 23:43 Nach oben    #7
Erfahrener Benutzer
 
Benutzerbild von JumperII
 
Registriert seit: 27.02.2006
Beiträge: 146
Standard

Es gibt für XML Parser an dieser Stelle keine allgemein verbindliche Aussage. Daher setzen die meisten sequentiell arbeitenden Parser (Streaming Parser) an dieser Stelle auf der abzuarbeitenden Grammatik auf. Bei dieser werden die verarbeitbaren Atome umgesetzt. D.h. für den cdata-Bereich, dass Plain Text von codes (mit & beginnend) z.b. getrennt werden. Wenn an dieser Stelle der von Dir gewünschte Speichereffekt auftreten soll, muss der Parser daher bereits Zustände und Daten vorhalten, so dass die Funktionsbeschreibung "sequentiell abarbeitender Parser" nicht mehr korrekt ist. Dabei werden natürlich untergeordnete Elemente und die Verarbeitung der cdata Elemente nicht berücksichtigt, d.h. diese können an dieser Stelle zusätzlich mit weiterführenden Sinnbedeutungen je nach vorliegenden Fall unzterschiedlich bewertet werden. Z.b. steht die Frage wie in <zeit> eingebettete weitere Tags auf den durch <zeit> begrenzte cdata reagieren soll. Ergo gibt es an dieser stelle keine universelle lösung und daher werden die einzelnen Elemente (durchaus typisch) so einzeln nacheinander angesprochen.

Gruß,
Jumper, the II.

PS: Ist wie beim Starten eines Autos ... früher musste man den Schock ziehen, drei mal Gas treten und anschließend erst das auto anlassen. Der heutigen Automatisierung und Bequemlichkeit werden diese Vorgänge vom Bordcomputer ausgeführt. Der Aufwand ist halt der Bordcomputer, der u.a. diese Funktionalität kapselt.
JumperII ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 14.02.2007, 23:53 Nach oben    #8
Erfahrener Benutzer
 
Benutzerbild von JumperII
 
Registriert seit: 27.02.2006
Beiträge: 146
Standard

Sorry, dass ich das nächste gleich in einen neuen Beitrag setze, aber ich denke, die Trennung vereinfacht die Struktur (Meinetwegen streicht mir pauschal die Beiträge im Status )

Zur Aussage, warum die Trennung - Dazu muss man sich die zu bewertende Grammatik im Parser betrachten. Ich möchte jetzt hier weder die Grundsatzerläuterungen für Links- und rechts-Rekursiv arbeitende Grammatiken und deren Umsetzungen als Parser eingehen. Um es zu vereinfachen, für die Auswertung eines XML Tags wird der Inhalt vereinfacht wie folgt bewertet:



Wichtig ist, dass an dieser Stelle der Eingansstream alias Datei byteweise analysiert wird. Für eine UTF-8 und UTF-16 sowie andere Codetables notwendige Anpassungen lasse ich der Einfachheit halber weg. Genauso die Attribute der Elemente, da sie durch wiederholende, eindeutig definierte Strings ohne weitere Auswertungsfunktionen realisiert sind.

Gruß,
Jumper, the II.

Geändert von JumperII (15.02.2007 um 01:02 Uhr).
JumperII ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 15.02.2007, 09:54 Nach oben    #9
Erfahrener Benutzer
 
Registriert seit: 30.10.2005
Beiträge: 279
Standard

Also ich habs jetzt gelöst. Ist vielleicht ne Art Workaround.

PHP-Code:
if(!isset($this->rows[$this->count][$this->currentrowelement])) {
              
$this->rows[$this->count][$this->currentrowelement] = $cdata;
          } else {
              
$this->rows[$this->count][$this->currentrowelement] .= $cdata;
          } 
Da mir durch das &amp; etwas überschrieben wurde hänge ich es nun einfach an das nächste (falls es bereits existiert). Ich mach das mit if ansonsten krieg ich durch error reporting zig Warnungen.

Nun ja danke für die Hilfe auch wenn nicht alles kapiert hab.
ex³ ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 15.02.2007, 10:53 Nach oben    #10
Martin Breuer
 
Benutzerbild von WarrenFaith
 
Registriert seit: 17.08.2005
Ort: Berlin
Beiträge: 1.642
Standard

Versuch mal statt &amp; einfach "&# 38;" zu nehmen. (ohne Leerzeichen bitte, aber das Forum wandelt das sonst in ein & um...)
Das wird bei XHTML akzeptiert und könnte für reines XML vielleicht auch besser sein?!
Quelle:
http://www.arch.cam.ac.uk/comp/ac049/ (fast ganz unten)
__________________
I did it my way - Senseless-Blog
WarrenFaith ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 15.02.2007, 14:03 Nach oben    #11
Erfahrener Benutzer
 
Registriert seit: 30.10.2005
Beiträge: 279
Standard

Nun ja das ist recht kompliziert dort einzubauen, schließlich müsste ich die Input File ja vorher durchparsen und das &amp; ersetzen, weil während des Parsens geht das ja nicht. Ich lass das besser so wie es jetzt is.
ex³ ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 15.02.2007, 14:51 Nach oben    #12
Erfahrener Benutzer
 
Benutzerbild von JumperII
 
Registriert seit: 27.02.2006
Beiträge: 146
Standard

Es würde dir auch nichts bringen, da cdata trotzdem nach altbekannterweise getrennt wird ... also "13", "&" und "15 Uhr".

Gruß,
Jumper, the II.
JumperII ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Antwort

Lesezeichen


Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)
 
Themen-Optionen

Forumregeln
Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
XML Parser mit PHP4 Eyüp PHP-Programmierung 4 24.06.2007 16:20
[Java] Parser Generierung mit JavaCC - Eine Einführung pago Tutorials 0 14.04.2006 11:54
MySQL 5.1 kommt in die Beta-Phase Ben Nachrichten 1 02.03.2006 14:31
PHP 4.4.1 veröffentlicht (Bugfix release) Ben Nachrichten 0 01.11.2005 17:12


Alle Zeitangaben in WEZ +2. Es ist jetzt 00:37 Uhr.


Powered by vBulletin® Version 3.7.3 (Deutsch)
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.2.0

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44