[PHP] XML nodes aanpassen met simplexml

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • posttoast
  • Registratie: April 2000
  • Laatst online: 00:32
In het kader van "iets nieuws proberen" ben ik een beetje aan het spelen met simplexml in PHP. Ik heb de volgende situatie:

Er is een XML-bestand (data.xml) met daarin allerlei nodes. Ik wil met een simpel stukje PHP op basis van die basis-xml een nieuw XML bestand maken. Met een aantal aanpassingen. Nu is de inhoud van data.xml variabel, dus wil ik mijn PHP script ook variabel opzetten. Ik heb daarom in het XML bestand wat metadata aan de nodes meegegeven zodat mijn PHP script weet hoe ermee omgegaan moet worden. Voorbeeld:
XML:
1
<text allow_edit="1" type="inline" id="button_close" description="Close button">CLOSE</text>


In mijn PHP script open in met simplexml_load_file() het XML bestand en loop er vervolgens doorheen om in een formulier <input>'s te maken. XML-nodes met type="inline" krijgen een <input type="text"> en nodes met een type="multiline" krijgen een <textarea>. De name-values van die inputs haal ik uit het id-attribuut van de XML-node. Zo ver, zo goed.

Maar nu het stukje waaruit blijkt dat mijn PHP-skills niet helemaal je van het zijn. Want: hoe sla ik het op? Ik heb zelf bedacht dat ik (nadat het formulier gesubmit is) nog een keer door de basis XML loop en vervolgens per node kijk of er een $_POST variabele is die correspondeert met het id van die node (dus $_POST[$nodeID]).

Hier gaat het volledig mis. Dit is wat ik nu heb:
PHP:
1
2
3
4
5
6
foreach ($xmlSource->texts->text as $text){
  $id = (string) $text['id'];
  if (isset($_POST[$id])){
    $text = $_POST[$id];
  }
}

Buiten het feit dat ik om aan $id te komen eerst dat ding expliciet naar een string moet casten (vind ik smerig, maar ik weet niet hoe het netter moet), werkt dit niet. Als ik nu de XML-source output krijg ik gewoon de onaangepaste XML te zien. En ik snap ook wel waarom: als ik $text = $_POST[$id]; doe pas ik alleen de instantie van $text in die iteratie van de foreach-loop aan.

Maar wat ik niet snap is: hoe doe ik dit wel? Volgens mij zit ik totaal in de verkeerde richting te denken, dus een zetje de goede kant op zou mij zeer blij maken :)

omniscale.nl


Acties:
  • 0 Henk 'm!

  • GlowMouse
  • Registratie: November 2002
  • Niet online

Acties:
  • 0 Henk 'm!

  • posttoast
  • Registratie: April 2000
  • Laatst online: 00:32
Dank, dat kende ik nog niet. Alleen als ik een & voor $text zet bovenin die foreach() dan krijg ik deze melding:
Fatal error: An iterator cannot be used with foreach by reference

Ik denk trouwens inmiddels dat ik het precies verkeerd om aanpak. In plaats van loopen door de XML zou ik door de $_POST heen moeten loopen. Ik ga daar nu nog eens wat mee proberen. Als ik echt rare dingen aan het doen ben dan is een tik op de vingers welkom ;)

[ Voor 42% gewijzigd door posttoast op 08-08-2011 17:57 ]

omniscale.nl


Acties:
  • 0 Henk 'm!

  • naam
  • Registratie: Oktober 2007
  • Laatst online: 12-09 13:07
Je zou de foreach loop om kunnen vormen naar een for loop.

PHP:
1
2
3
4
5
6
7
8
9
$texts = $xmlSource->texts->text;
for($i = 0; $i < count($texts); $i++)
{
  $id = $texts[$i]['id'];
  if(isset($_POST[$id]))
  {
    $texts[$i] = $_POST[$id];
  }
}


Daarin is het wel mogelijk om teksten aan te passen.

Acties:
  • 0 Henk 'm!

  • posttoast
  • Registratie: April 2000
  • Laatst online: 00:32
Bedankt! Maar volgens mij heb ik een nog nettere oplossing gevonden:
PHP:
1
2
3
4
  foreach ($_POST as $key => $value){
    $item = $xmlSource->xpath("//text[@id='".$key."']");
    $item[0][0] = $value;
  }


Ik loop nu dus juist door de $_POST heen in plaats van door de XML. Is ook logischer, want wellicht staan er allerlei nodes tussen die helemaal niet in de $_POST staan. Dat is dus "zonde".

Is wat ik nu doe een beetje OK, of krijg ik nu straks de PHP-politie achter me aan?

omniscale.nl


Acties:
  • 0 Henk 'm!

  • GlowMouse
  • Registratie: November 2002
  • Niet online
Volgens mij pas je $xmlSource nu niet aan, en de check allow_edit="1" ontbreekt.

Acties:
  • 0 Henk 'm!

  • posttoast
  • Registratie: April 2000
  • Laatst online: 00:32
Een test leert mij dat $xmlSource wel degelijk wordt aangepast.

Die check doe ik inderdaad nog niet, maar ik wilde het een beetje eenvoudig houden voor het voorbeeld.

omniscale.nl


Acties:
  • 0 Henk 'm!

  • ReenL
  • Registratie: Augustus 2010
  • Laatst online: 14-09-2022
Php.net
The SimpleXML extension provides a very simple and easily usable toolset to convert XML to an object that can be processed with normal property selectors and array iterators.
SimpleXML is eigenlijk voor het lezen van XML, niet zo zeer voor het maken van een XML. Hiervoor heb je XMLWriter.

Echter bij het aanpassen van een bestande XML is SimpleXML wel bruikbaar, asXML gebruiken na je aanpassing en dat weer wegschrijven.

Het grote nadeel van SimpleXML is dat hij de complete file in 1 keer in memory laad, je kunt dus niet met al te grote files werken.

Dat verhaal met xpath heb je inderdaad goed begrepen, dat lijkt mij ook de beste oplossing in dit geval.

Acties:
  • 0 Henk 'm!

Verwijderd

Ik heb de SimpleXml eigenlijk nooit echt als 'simple' gezien en maak vaker gebruik van de DomDocument class die zowel XML als HTML (of andere ML) kan lezen, modificeren en schrijven.
Pagina: 1