[php5/simplexml] Raar gedrag van xpath

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Steven
  • Registratie: December 2000
  • Laatst online: 05-07 21:17
Goededag,

Ik ben met wat grote XML bestanden bezig, en om het een en andere wat sneller en praktischer te houden maak ik gebruik van xpath queries die weer gedaan worden op een resultaat van xpath.

voorbeeld:
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
<?
$xml = '
<xml>
<a>
    <b id="blaat">
        <c>test</c>
        <c>test2</c>
        <c>test3</c>
    </b>
    <b id="schaap">
        <c>bla</c>
        <c>bla2</c>
        <c>bla3</c>
    </b>
</a>
</xml>';

$el = simplexml_load_string($xml);
foreach ($el->xpath("//b") as $bEl) {
    echo 'Found a b with id:' . $bEl->Attributes()->id . "\n";
    foreach ($bEl->xpath("//c") as $cEl) {
        echo 'Found an c with value:' . (string) $cEl . "\n";
    }
}
?>


Het verwachte resultaat zou zijn:
code:
1
2
3
4
5
6
7
8
Found a b with id:blaat
Found an c with value:test
Found an c with value:test2
Found an c with value:test3
Found a b with id:schaap
Found an c with value:bla
Found an c with value:bla2
Found an c with value:bla3


Echter tot mijn grote verbazing is het resultaat:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Found a b with id:blaat
Found an c with value:test
Found an c with value:test2
Found an c with value:test3
Found an c with value:bla
Found an c with value:bla2
Found an c with value:bla3
Found a b with id:schaap
Found an c with value:test
Found an c with value:test2
Found an c with value:test3
Found an c with value:bla
Found an c with value:bla2
Found an c with value:bla3



Dat is toch helemaal niet logisch. Sterker nog, als ik vlak voor de 2de foreach dit neerzet werkt het wel:
PHP:
1
$bEl = simplexml_load_string($bEl->asXML());


Iemand enig idee?!?

Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Geen idee to be honest, maar moet:
PHP:
1
$bEl->xpath("//c")

niet
PHP:
1
$bEl->xpath("c")

zijn?

Met //c zeg je volgens mij: geef mij alle c elementen die je in de root op elke willekeurige diepte vindt.

[ Voor 31% gewijzigd door RobIII op 14-01-2010 21:16 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

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

Niemand_Anders

Dat was ik niet..

Het probleem is dat '//' altijd vanuit de root wordt uitgevoerd. Als je './/' gebruikt werk je vanaf je huidige path.

Echter als je met echt grote XML bestanden (100+ MB) aan het werken bent, kun je beter kijken naar een SAX parsers. Je checkt dan gewoon elk element op degene welke je wilt hebben ('b'). Vervolgens lees je de volledige 'b' node uit en kun je hem eventueel alsnog als DOM document verwerken. Maar DOM documenten nemen al snel erg veel resources (geheugen) in beslag, waardoor in je in de meeste gevallen gewoon beter alles kunt vervwerken met de SAX parser..

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


Acties:
  • 0 Henk 'm!

  • Steven
  • Registratie: December 2000
  • Laatst online: 05-07 21:17
.// werkt inderdaad. Ik had verwacht dat een los element zichzelf als root ziet, vooral omdat print_r() geen verbindingen achterhaald met de bovenliggende elementen. Weer wat geleerd, bedankt!