php en dom xml

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Explore
  • Registratie: Maart 2001
  • Laatst online: 08-04-2011

Explore

Op zoek naar werk

Topicstarter
De dom xml die php standaard levert is nog expirimental en bovendien is er een library voor nodig, die wellicht niet geinstalleerd is bij een ISP. Op www.phpclasses.org was ook niks zinnigs te vinden, dus heb ik zelf een dom xml library gemaakt. Deze werkt inmiddels perfect, inclusief de mogelijkheid xml documenten naar andere servers/services te sturen via een socket connection.

Erg cool allemaal, maar ik zat me af te vragen of er een methode is om de appendChild net zo te laten werken als bv. in Actionscript. Daar kan je namelijk het volgende doen:

Flash ActionScript:
1
2
3
4
5
6
7
8
9
var ding = new XML();

var child = ding.createElement('child');
child.attributes['nummer'] = 1;
ding.appendChild('child');

var subchild = ding.createElement('subchild');
subchild.createTextNode('Deze subchild hangt onder child nr. 1');
child.appendChild('subchild');


Het gaat 'm dus om die laatste regel: die hangt nog een child aan een al eerder toegevoegde child, welke dan dus automatisch ook aan het root-element wordt toegevoegd.

't Is misschien een beetje moeilijk uit te leggen, maar iemand die XML begrijpt, snapt wel wat ik bedoel, denk ik.

In PHP krijg ik dit niet voor elkaar, aangezien 'child' geen ref heeft naar het root-element. Dus die laatste appendChild hangt het subchild wel braaf aan child, maar niet aan de child in het root-element ('ding').

Is er een methode om dit toch goed te laten werken in PHP?

Edit: typo.

Edit: Nu ik zo m'n eigen bericht nog eens lees, denk ik dat ik een heel eind kom door goed gebruik te maken van parentNode en call-by-reference... Hm... :P

[ Voor 15% gewijzigd door Explore op 20-12-2002 10:56 ]

[ specs ] [ Tweaker gallery ]


Acties:
  • 0 Henk 'm!

  • CyberSnooP
  • Registratie: Augustus 2000
  • Laatst online: 16-08 06:44

CyberSnooP

^^^^ schrijft --->

Explore schreef op 20 december 2002 @ 10:44:
In PHP krijg ik dit niet voor elkaar, aangezien 'child' geen ref heeft naar het root-element. Dus die laatste appendChild hangt het subchild wel braaf aan child, maar niet aan de child in het root-element ('ding').
Moeten je subchild dan apart aan het root-element komen te hangen? Als je iets toevoegt aan een child wil je toch juist niet dat het aan het root-element hangt?

Ik verwacht echter dat je een probleem hebt zodra je vanuit je ding[ de hele XML-code wilt gaan bouwen. Dat komt dan echter omdat je object $child wat je als return waarde van createElement() hebt gekregeren een kopie (clone?) is van het child object wat intern in ding wordt gemaakt in plaats van een reference daarna.

Bestuurdeer de paragraaf over references in PHP nog eens een goed. Als je $child hetzelfde object representeert als er in je ding (root-element) wordt vermeld hebben ze altijd dezelfde childs.

|_____vakje______|


Acties:
  • 0 Henk 'm!

Verwijderd

gebruik je strings om die append te doen of append je daadwerkelijk een object?
In het eerste geval: gebruik geen strings maar objecten (je kan anders altijd variable variable gebruiken maar dat vind ik vies)
In het tweede geval is er geen probleem lijkt me

Acties:
  • 0 Henk 'm!

  • Explore
  • Registratie: Maart 2001
  • Laatst online: 08-04-2011

Explore

Op zoek naar werk

Topicstarter
CyberSnooP schreef op 20 december 2002 @ 10:57:
[...]

Moeten je subchild dan apart aan het root-element komen te hangen? Als je iets toevoegt aan een child wil je toch juist niet dat het aan het root-element hangt?
Nee, die subchild in 't voorbeeldje moet aan child hangen en niet meteen aan het root-element. Het root-element moet natuurlijk wel worden aangepast als je de subchild aan de child hangt. Dat gebeurd op 't moment dus niet als ik iets dergelijks als in 't voorbeeld probeer in PHP.
Ik verwacht echter dat je een probleem hebt zodra je vanuit je ding[ de hele XML-code wilt gaan bouwen. Dat komt dan echter omdat je object $child wat je als return waarde van createElement() hebt gekregeren een kopie (clone?) is van het child object wat intern in ding wordt gemaakt in plaats van een reference daarna.
Nee, createElement maakt een nieuw op-zich staand xml object aan. Er wordt dus nog niks aan het root-element gehangen bij een createElement. Dat gebeurd pas met de call naar appendChild.
Bestuurdeer de paragraaf over references in PHP nog eens een goed. Als je $child hetzelfde object representeert als er in je ding (root-element) wordt vermeld hebben ze altijd dezelfde childs.
Ehm... ik zal eens wat meer met references aan de gang gaan.

Btw: ik werk inderdaad direct met objecten (classes) en niet met strings.

[ specs ] [ Tweaker gallery ]


Acties:
  • 0 Henk 'm!

  • Genoil
  • Registratie: Maart 2000
  • Laatst online: 12-11-2023
ik heb hier laatst ook mee lopen prutsen, misschien heb je hier wat aan. Het voorbeeld werkt niet met dieper geneste nodes, maar ik denk wel dat het hiermee lukt, het ging me er namelijk om een child by reference uit een tree te vissen en er iets aan te veranderen op zo'n manier dat de node in de boom zelf ook meeveranderde.

edit: dit topic gaat ook over het probleem, maar is wat vager :)

[ Voor 21% gewijzigd door Genoil op 20-12-2002 11:57 ]


Acties:
  • 0 Henk 'm!

  • Explore
  • Registratie: Maart 2001
  • Laatst online: 08-04-2011

Explore

Op zoek naar werk

Topicstarter
Hm, dit valt nog tegen... Ik raak mezelf kwijt in parents, childs, recursie en references. :)
Op een of andere manier heeft de parent (1) van de parent (2) waar ik het child aan wil toevoegen geen child nodes, wat natuurlijk niet kan kloppen, aangezien parent (2) een child is van parent (1). right? :? Het pass-by-reference principe heb ik inmiddels aardig door, maar toch loopt er iets spaak ergens.

Die links van Genoil zijn inderdaad een beetje vaag, al doe je ongeveer hetzelfde als wat ik probeer te doen (dat zie ik nog wel). Een &get_child function had ik ook al gemaakt, werkt 't zelfde als die van jou - alhans... Die werkt dus niet goed.

Mijn get_child ziet er zo uit (de echo's zijn effe voor de debug):

PHP:
1
2
3
4
5
6
7
8
9
function &get_child($nodeName) {
   echo "get child list from this object: ".
      ($this->nodeName?$this->nodeName:"root")."<br>";
   if (gettype($this->childNodes) == 'NULL') return null;
   foreach ($this->childNodes as $child) {
      if ($child->nodeName == $nodeName) return $child;
   }
   return null;
}


En deze wordt aangeroepen in dit stukje code:

PHP:
1
2
3
4
5
6
7
if (gettype($this->parentNode) == 'object') {
   echo "Trying to append child <b>".$childNode->nodeName."</b>";
   echo " to parent <b>".($this->parentNode->nodeName?
      $this->parentNode->nodeName:"root")."</b><br>";
   $test =& $this->parentNode->get_child($this->nodeName);
   echo $test->nodeName."<br>";
}


De namen die worden weergegeven kloppen, alleen blijkt dat if-statement (childNodes == null) TRUE op te leveren, dus gebeurd er niks....

I'm stumped!

Edit: layout was messed up.

[ Voor 13% gewijzigd door Explore op 20-12-2002 12:58 ]

[ specs ] [ Tweaker gallery ]


Acties:
  • 0 Henk 'm!

  • hobbit_be
  • Registratie: November 2002
  • Laatst online: 04-07 12:07
ik raad je aan om je eigen XML object structuur te maken - is 'poep' simpel en ineens ben je dan compatibel overal. Wat speed reduction moet je ermaar bij nemen. Wil je eventueel mijn code doorgeven (onno@onnos.com). Daar zit ook ineens een 'simpel' xpath parserke bij zodat je kunt: xmlDoc->getNode("images[4]/hello[1]"); (heb ik ook voor actionscript gemaakt...). Let wel is gemaakt vcor duidelijkheid en het kan dus sneller (bijvoorbeeld de xml strcutuur van XPath Parser v3.0)... Oh en met PHP kun je geen references vergelijken (zover ik weet))... Tis geen C++ he (snif)

Acties:
  • 0 Henk 'm!

  • Genoil
  • Registratie: Maart 2000
  • Laatst online: 12-11-2023
hmm lastig te formuleren, maar ik probeer het ff. Je wilt dus een 'tree' krijgen met:
A->B->C
maar je krijgt:
A->B1
B2->C

is het toevallig zo dat je wanneer je je C aan B wilt toevoegen, eerst je get_child op A aanroept? zo ja, ditch dan je foreach, en fiets op deze manier door je children heen:

PHP:
1
2
3
4
5
6
7
8
9
10
function &getChild($sName) 
    {     
        for($n = 0; $n < count($this->m_aChildren) ; $n++) 
        { 
            if($this->m_aChildren[$n]->m_sName == $sName) 
            { 
                return $this->m_aChildren[$n]; 
            } 
        }     
    }


foreach maakt namelijk een copy van elke node in je array...

edit: hmm ik begin hier een beetje aan te twijfelen...dat script in die post heb ik namelijk in een later stadium nog een beetje opgepoetst, kweet ff niet zeker meer of ik later niet alsnog weer foreach heb gebruikt... en ik heb dat script op m'n werk liggen dus

[ Voor 21% gewijzigd door Genoil op 20-12-2002 13:20 ]


Acties:
  • 0 Henk 'm!

  • Explore
  • Registratie: Maart 2001
  • Laatst online: 08-04-2011

Explore

Op zoek naar werk

Topicstarter
Genoil schreef op 20 december 2002 @ 13:17:
hmm lastig te formuleren, maar ik probeer het ff. Je wilt dus een 'tree' krijgen met:
A->B->C
maar je krijgt:
A->B1
B2->C
Ja en nee. Ik wil inderdaad de tree A->B->C maar ik krijg A, de rest verdwijnt momenteel.
is het toevallig zo dat je wanneer je je C aan B wilt toevoegen, eerst je get_child op A aanroept?
Ja.
zo ja, ditch dan je foreach, en fiets op deze manier door je children heen:

[...]
Daar zit 'm 't probleem niet, denk ik.
Ik voer namelijk eerst een test uit:

PHP:
1
if (gettype($this->childNodes) == 'NULL') return null;


En die levert al TRUE op, dus wordt die foreach-loop helemaal niet gedraait.

Die '$this' in dat if-statement verwijst, als het goed is naar de parent-node waaraan ik het child wil toevoegen (zie m'n stukjes code hierboven).

Overigens, voor de duidelijkheid, hier heel mijn appendChild method:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
function appendChild(&$childNode) {
   $childNode->parentNode = $this;

   if (gettype($this->parentNode) == 'object') {
      echo "Trying to append child <b>".$childNode->nodeName."</b>";
      echo " to parent <b>".($this->parentNode->nodeName?
         $this->parentNode->nodeName:"root")."</b><br>";
      $test =& $this->parentNode->get_child($this->nodeName);
      echo $test->nodeName."<br>";
   }

   $this->childNodes[] = $childNode;
   $last = count($this->childNodes);
   if ($last > 1) {
      for ($j = $last-1; $j >= 0; $j--)
         $this->childNodes[$j]->nextSibling = $this->childNodes[$j + 1];
      for ($j = 1; $j < $last; $j++)
         $this->childNodes[$j]->previousSibling = $this->childNodes[$j - 1];
   }
   $this->firstChild = $this->childNodes[0];
   $this->lastChild = $this->childNodes[($last-1) % $last];
}


Dat eerste if-statement heb ik toegevoegd in een poging die references in orde te krijgen. De rest van de code in deze method werkt prima (al zou je verwachten dat die 2 loopjes makkelijker zouden kunnen, maar dat terzijde).

[ specs ] [ Tweaker gallery ]


Acties:
  • 0 Henk 'm!

  • Explore
  • Registratie: Maart 2001
  • Laatst online: 08-04-2011

Explore

Op zoek naar werk

Topicstarter
Nog effe dit...
hobbit_be schreef op 20 december 2002 @ 13:09:
ik raad je aan om je eigen XML object structuur te maken - is 'poep' simpel en ineens ben je dan compatibel overal.
Dat heb ik nu dus. Ik volg gewoon de dom spec, dus je kan nu dit soort dingen doen:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
include('xml.php');

$qXML = new XML();
$msgEl = $qXML->createElement('message');
$msgEl->attributes['id'] = '12345';

$qEl = $qXML->createElement('query');
$qEl->attributes['bla'] = 'someattr';

$crdEl = $qXML->createElement('coord');
$crdEl->attributes['x'] = 1800;
$crdEl->attributes['y'] = 2000;

$qEl->appendChild($crdEl);
$msgEl->appendChild($qEl);
$qXML->appendChild($msgEl);


Punt van dit topic is dat ik na elke createElement het gemaakt child gelijk wil toevoegen aan z'n parent. Dit dus:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
include('xml.php');

$qXML = new XML();
$msgEl = $qXML->createElement('message');
$msgEl->attributes['id'] = '12345';
$qXML->appendChild($msgEl);

$qEl = $qXML->createElement('query');
$qEl->attributes['bla'] = 'someattr';
$msgEl->appendChild($qEl);

$crdEl = $qXML->createElement('coord');
$crdEl->attributes['x'] = 1800;
$crdEl->attributes['y'] = 2000;
$qEl->appendChild($crdEl);


Maar dat wil niet goed werken.
Wat speed reduction moet je ermaar bij nemen. Wil je eventueel mijn code doorgeven (onno@onnos.com). Daar zit ook ineens een 'simpel' xpath parserke bij zodat je kunt: xmlDoc->getNode("images[4]/hello[1]"); (heb ik ook voor actionscript gemaakt...). Let wel is gemaakt vcor duidelijkheid en het kan dus sneller (bijvoorbeeld de xml strcutuur van XPath Parser v3.0)... Oh en met PHP kun je geen references vergelijken (zover ik weet))... Tis geen C++ he (snif)
Ah, is dat xpath. :)
Ik vond het al zo'n vage notatie. Ik hou het voorlopig effe bij m'n huidige aanpak, denk ik. Alleen wil ik het liever zoals in het tweede stukje code, aangezien dat duidelijk makkelijker werkt dan de eerste.

Wat bedoel je met references vergelijken?

[ Voor 30% gewijzigd door Explore op 20-12-2002 13:56 ]

[ specs ] [ Tweaker gallery ]


Acties:
  • 0 Henk 'm!

  • Genoil
  • Registratie: Maart 2000
  • Laatst online: 12-11-2023
hm jammer dat ik hier nu geen php ter beschikking heb...dus het blijft bij een gokje. ik zie 1 cruciaal verschil tussen mijn addChild en jouw appendChild:

PHP:
1
2
3
4
function addChild(&$cNode) 
{ 
    $this->m_aChildren[] = &$cNode; 
}


2 keer & dus...ik heb hier geloof ik es een vage esoterische verklaring voor bedacht, maar het zou ook heel goed kunnen dat m'n huidige versie van het script die dubbele & niet meer heeft...desalniettemin, trial & error kan soms bijzonder goed helpen :7

edit:
esotherische verklaring

[ Voor 12% gewijzigd door Genoil op 20-12-2002 15:10 ]


Acties:
  • 0 Henk 'm!

  • Explore
  • Registratie: Maart 2001
  • Laatst online: 08-04-2011

Explore

Op zoek naar werk

Topicstarter
Well darn! Het werkt! :)
Heel die zooi met zoeken naar parents in childs en bla is niet meer nodig! Die ene & was voldoende om heel de zooi te fixen. Ik dacht dat die reference in de functie-call al voldoende was... THANKS!

[ specs ] [ Tweaker gallery ]


Acties:
  • 0 Henk 'm!

  • Genoil
  • Registratie: Maart 2000
  • Laatst online: 12-11-2023
cool, probeer anders ook nog ff zonder &'s. Als het idd waar is (volgens mijn esotherische verklaring;)) dat object-instances 'by default' al een reference zijn, zou dat ook moeten werken. maar ja iig cool dat je er uit bent! suffe &'s in PHP ook :)

Acties:
  • 0 Henk 'm!

  • Explore
  • Registratie: Maart 2001
  • Laatst online: 08-04-2011

Explore

Op zoek naar werk

Topicstarter
Nee, alle &'s staan nu waar ze moeten staan (2 maar):

PHP:
1
2
3
4
function appendChild(&$childNode) {
   $childNode->parentNode = $this;
   $this->childNodes[] = &$childNode;
   // ...



Dat werkt perfect. Heel die if-zooi die er voor stond kon weg en de get_child method ook.
Als ik 1 van die &'s weghaal, dan werkt 't niet meer.
Ik heb al geen zin meer om er over na te denken na een paar uur klooien. Ik ben blij dat het nu werkt zoals ik wil en zoals het hoort!

Maaruh, ik zie dat je een quest hebt gemaakt van dit issue! :)

[ specs ] [ Tweaker gallery ]


Acties:
  • 0 Henk 'm!

  • CyberSnooP
  • Registratie: Augustus 2000
  • Laatst online: 16-08 06:44

CyberSnooP

^^^^ schrijft --->

Explore schreef op 20 december 2002 @ 16:04:
Nee, alle &'s staan nu waar ze moeten staan (2 maar):
Genoil schreef op 20 december 2002 @ 13:17:
hmm lastig te formuleren, maar ik probeer het ff. Je wilt dus een 'tree' krijgen met:
A->B->C
maar je krijgt:
A->B1
B2->C
Dus Genoil had toch gelijk?
(en ik ook een beetje aangezien je probleem in het references systeem van PHP zat?)

|_____vakje______|


Acties:
  • 0 Henk 'm!

  • hobbit_be
  • Registratie: November 2002
  • Laatst online: 04-07 12:07
oppassen met de references - hangt van PHP versie af... in ieder geval telkens je een
reference = reference doet wel effe de eerste UNSETten en steeds een ref = &ref...
ik zou dus ook:
previousSibling = &$this->childNodes
en nog eerste die previousSibling unsetted...
en ALTIJD iets = &new XML(); //anders gaat ie heel het object copieren na je nieuw...
een reference is geen pointer he...

Acties:
  • 0 Henk 'm!

  • Apollo_Futurae
  • Registratie: November 2000
  • Niet online
hobbit_be schreef op 20 december 2002 @ 17:24:
en ALTIJD iets = &new XML(); //anders gaat ie heel het object copieren na je nieuw...
ik mag toch hopen dat die extra copy weggeoptimaliseerd wordt :?

Pas de replâtrage, la structure est pourrie.


Acties:
  • 0 Henk 'm!

  • CyberSnooP
  • Registratie: Augustus 2000
  • Laatst online: 16-08 06:44

CyberSnooP

^^^^ schrijft --->

Apollo_Futurae schreef op 20 December 2002 @ 23:03:
ik mag toch hopen dat die extra copy weggeoptimaliseerd wordt :?
Hopen mag, maar het schijnt inderdaad altijd een kopie op te leveren. Jammer genoeg is PHP over dit soort dingen nooit echt duidelijk naar buiten.

Ik verwacht wel dat waarden waar geen varaibele naar verwijst op bepaalde momenten worden vrijgegeven, maar er wordt niet bijster veel geöptimaliseerd.. het is slechts een parser&interpreter en geen volledige compiler die daar de tijd voor neemt, helaas!

|_____vakje______|


Acties:
  • 0 Henk 'm!

  • Apollo_Futurae
  • Registratie: November 2000
  • Niet online
ach ja
ik begin php steeds rommeliger te vinden :)

Pas de replâtrage, la structure est pourrie.


Acties:
  • 0 Henk 'm!

  • hobbit_be
  • Registratie: November 2002
  • Laatst online: 04-07 12:07
ay! k begin ook al te denken dat java sneller is - jsp here i come ;).
Maar PHP blijft wel het gemakkelijkst voor simple en snelle gevallen.
Voor een CMS heb ik 200K+ code en dat begint serieus door te wegen.

Nu maar hopen dat de target Host Zend heeft...

Oh nog een tip: gebruikt de array structuur voor objecten/records... PHP is vree
traag met 'classes'...
Pagina: 1