[PHP] SimpleXML / Xpath : Bug of feature?

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • SchizoDuckie
  • Registratie: April 2001
  • Laatst online: 18-02 23:12
Ik zit hier even te klooien met een testcase van de grootste wtf die ik de laatste tijd tegengekomen ben in PHP 5 (laatste versie: 5.2.6)

Aanschouw de volgende listings:

XML: test.xml
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
<?xml version="1.0" encoding="Windows-1252" standalone="yes" ?>
<AVXML>
   <EBUSMSGSRS>
      <EBUSQRYRS>
        <RECORD>
           <RECID>0000001939</RECID>
            <FIELD TYPE="C"><NAME>rec_id</NAME><VALUE>0000001939</VALUE></FIELD>
            <FIELD TYPE="C"><NAME>servicenr</NAME><VALUE>0900-123412341234</VALUE></FIELD>
            <FIELD TYPE="C"><NAME>art_code</NAME><VALUE>500</VALUE></FIELD>
            <FIELD TYPE="C"><NAME>art_desc1</NAME><VALUE>Abonnementskosten</VALUE></FIELD>
            <FIELD TYPE="Y"><NAME>px_sell</NAME><VALUE>45</VALUE></FIELD>
        </RECORD>
        <RECORD>
           <RECID>0000001940</RECID>
            <FIELD TYPE="C"><NAME>rec_id</NAME><VALUE>0000001940</VALUE></FIELD>
            <FIELD TYPE="C"><NAME>servicenr</NAME><VALUE>0900-123412341234</VALUE></FIELD>
            <FIELD TYPE="C"><NAME>art_code</NAME><VALUE>511</VALUE></FIELD>
            <FIELD TYPE="C"><NAME>art_desc1</NAME><VALUE>Netwerkwachtrij met prioriteitenstelling</VALUE></FIELD>
            <FIELD TYPE="Y"><NAME>px_sell</NAME><VALUE>45</VALUE></FIELD>
        </RECORD>
        <RECORD>
           <RECID>0000001941</RECID>
            <FIELD TYPE="C"><NAME>rec_id</NAME><VALUE>0000001941</VALUE></FIELD>
            <FIELD TYPE="C"><NAME>servicenr</NAME><VALUE>0900-123412341234</VALUE></FIELD>
            <FIELD TYPE="C"><NAME>art_code</NAME><VALUE>570</VALUE></FIELD>
            <FIELD TYPE="C"><NAME>art_desc1</NAME><VALUE>Belbundel 150 minuten</VALUE></FIELD>
            <FIELD TYPE="Y"><NAME>px_sell</NAME><VALUE>8.95</VALUE></FIELD>
        </RECORD>
      </EBUSQRYRS>
   </EBUSMSGSRS>
</AVXML>


PHP:
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
45
46
47
48
49
<style type='text/css'>
PRE{ font-size: 10px; border: 1px solid black; } 
</style>

<?php
class TestObject
{
    private $properties, $fields, $recordid;

    function __construct($input, $type='monthly')
    {
        $namestr = false;
        $valstr = false;
        $this->fields = $input;
        $this->properties = Array();
        $this->recordid = (String) $input->RECID;
        
        foreach($input->xpath('//FIELD') as $subfield)
 // hier gaat het mis, hij voert hier de xpath uit over de hele tree ipv het xml fragment
        {
            $namestr = (String) $subfield->NAME;
            $valstr = (String) $subfield->VALUE;
            $this->properties[$namestr] = $valstr; 
        }
    }

    function display() 
    {
        return("<ul>
            <li>Article code:  {$this->properties['art_code']}</li>
            <li>Description: {$this->properties['art_desc1']}</li>
            <li>Price: {$this->properties['px_sell']}</li>
        </ul>");
    }       
        
}


$xml = simplexml_load_file('test.xml');
$records = $xml->xpath("//RECORD");

foreach($records as $record)
{
    $product = new TestObject($record);
    echo "<h1>New Object instance:</h1> <pre>".print_r($product, true)."</pre><hr>";
    echo "<h3>Object display itself:</h3>".$product->display().'<hr>';  
}

?>


Op regel 18 gaat het de mist in, de xpath query lijkt niet uitgevoerd te worden over het XML fragment wat ik meepaas in de constructor, maar hij pakt gewoon keihard weer de complete XML boom terug, loopt hier 3x overheen aangezien elk record dezelfde properties heeft en zo wordt dus elk object gevuld met de zelfde private variables 8)7

Kan iemand me vertellen of ik de functie xpath gewoon niet goed begrijp (volgens mij moet je namelijk ook gewoon een xpath query los kunnen laten op een xml fragment ipv het complete document, of heb ik hier een bug gevonden?

Stop uploading passwords to Github!


Acties:
  • 0 Henk 'm!

  • masq
  • Registratie: September 2004
  • Laatst online: 18-04 00:18
Misschien werkt .//FIELD ipv //FIELD ?
. Selects the current node
aldus de XPath reference van w3schools.

Acties:
  • 0 Henk 'm!

  • Niemand_Anders
  • Registratie: Juli 2006
  • Laatst online: 09-07-2024

Niemand_Anders

Dat was ik niet..

XPath nodes zijn referenced objecten. Je zult je xpath moeten wijzigen naar .//RECORD (Let voor op voorloop punt). Het is dus geen bug.

Je kunt dit vergelijken met de 'cd' commando. Ondanks dat je al op een dieper niveau kunt zitten brengt / je weet terug naar de root.

If it isn't broken, fix it until it is..


Acties:
  • 0 Henk 'm!

  • SchizoDuckie
  • Registratie: April 2001
  • Laatst online: 18-02 23:12
Niemand_Anders schreef op vrijdag 18 juli 2008 @ 14:00:
XPath nodes zijn referenced objecten. Je zult je xpath moeten wijzigen naar .//RECORD (Let voor op voorloop punt). Het is dus geen bug.

Je kunt dit vergelijken met de 'cd' commando. Ondanks dat je al op een dieper niveau kunt zitten brengt / je weet terug naar de root.
Arg 8)7

Weer wat geleerd :) Ik had er geen idee van dat dat ding z'n references behoudt :)

Stop uploading passwords to Github!


Acties:
  • 0 Henk 'm!

  • Niemand_Anders
  • Registratie: Juli 2006
  • Laatst online: 09-07-2024

Niemand_Anders

Dat was ik niet..

Als een node niet zijn references behoud, hoe kun je anders dan zijn parent of siblings opvragen? :)

If it isn't broken, fix it until it is..


Acties:
  • 0 Henk 'm!

  • BHR
  • Registratie: Februari 2002
  • Laatst online: 17-09 21:58

BHR

Opzich werkt
PHP:
1
foreach($input->xpath('FIELD') as $subfield)

natuurlijk ook, aangezien FIELD een direct kind van RECORD is. Op deze manier kijk je alleen naar de directe children van RECORD. Naast sneller (bij grote/diep geneste documenten) is dit ook duidelijker, want je geeft hier expliciet aan op welk niveau FIELD moet zitten.

Tenzij FIELD ook dieper genest mag voorkomen, want gaat het hele verhaal niet op :p. Maar je voorbeeld lijkt daar niet op te wijzen.

No amount of key presses will shut off the Random Bug Generator

Pagina: 1