<?php
foreach ($invoice->xpath('//cac:Item') as $item) {
$cbc = $item->xpath('descendant::cbc:*'); // array van SimpleXMLElement objecten van alle onderliggende elementen met een cbc namespace
foreach ($cbc as $elt) {
echo $elt->getName().': '.$elt.'<br>'; // voor $elt wordt de __toString() methode aangeroepen
}
}
?>
Dit levert (met het XML document uit bovenstaande StackOverflow thread):
Description: TITLE
ID: 9789079995318
Name: Afnemer
Value: ABC
Op een soortgelijke wijze zou je de selectie van de Invoice elementen (ID, InvoicedQuantity) ook kunnen selecteren met de "XML axis" child::.
Bedankt! Ik ga het morgen gelijk testen. Ik dacht al dat het iets met de notatie te maken, maar dat er "descendents::" gebruikt moest worden was ik zelf zo niet opgekomen.
Ik ook niet, heb hier best lang op zitten zoeken, maar xpath is een ontzettend krachtige "querytaal" voor XML-structuren (waar ik verder nauwelijks iets van weet :p). Het is "gewoon" een kwestie van de juiste vraag (aan XML) formuleren, en dan uitzoeken hoe je dat opschrijft in het xpath-dialect.
Het is me bijna gelukt! Ik zit nog met één kleine issue en dan heb ik het opgelost. Ik heb me suf gezocht op de juiste selector(s). Ik snap nu je woorden dat het lastig te vinden is :P
In mijn originele foreach, waarin ik door alle invoicelines loop, heb ik een nieuwe foreach gemaakt met het doel om van de invoiceline in kwestie de "item" eruit te halen en deze waardes toe te voegen aan de originele array. Hiervoor heb ik je code gebruikt met 'descendant::cbc:*' om deze op te halen. Volgens heb ik deze in een nieuwe array gestopt met de naam van de node als de Key en de waarde als value. Deze array voeg ik dan weer toe aan de originele onder de key "item". Alleen komt er dan overal alleen 't laatste item uit de laatste invoiceline bij te staan.
Ik zie even niet wat ik fout doe, heb jij een idee?
<?php
//Init the array
$invoiceLineArray = [];
$itemArray = [];
foreach($ob->xpath('//cac:InvoiceLine') as $invoice)
{
$invoiceLineID = (string)$invoice->children('cbc', true)->ID.PHP_EOL;
$invoiceLineArray [$invoiceLineID]['ID'] = (string)$invoice->children('cbc', true)->ID.PHP_EOL;
$invoiceLineArray [$invoiceLineID]['Note'] = (string)$invoice->children('cbc', true)->Note.PHP_EOL;
$invoiceLineArray [$invoiceLineID]['InvoicedQuantity'] = (string)$invoice->children('cbc', true)->InvoicedQuantity.PHP_EOL;
$invoiceLineArray [$invoiceLineID]['LineExtensionAmount'] = (string)$invoice->children('cbc', true)->LineExtensionAmount.PHP_EOL;
foreach ($invoice->xpath('//cac:Item') as $item) {
$children = $item->xpath('descendant::cbc:*'); // array van SimpleXMLElement objecten van alle onderliggende elementen met een cbc namespace
//print_r($children); // -> deze print alle items uit elke invoiceline uit
foreach ($children as $child) {
// print_r($child);
$name = $child->getName();
$itemArray[$name] = $child.PHP_EOL;
// print_r($itemArray);
}
$invoiceLineArray [$invoiceLineID]['Item'] = $itemArray; // -> Maak een nieuwe key aan en vul deze met de items uit "Item"
}
}
//print_r( $itemArray, false );
print_r($invoiceLineArray, false); // -> print alleen het item uit de laatste invoiceline
?>
[size=xsmall]Toevoeging op 16/07/2020 11:10:48:[/size]
Een update, ben inmiddels wel its dichterbij gekomen.
Ben ik er achter gekomen dat ik op deze manier de ID van invoiceline nummer 3 kan pakken.
Nu bracht me dit op het volgende idee, een $count variabelen toevoegen aan de foreach, zodat ik weet om welke invoiceline het gaat. Vervolgens wil ik deze uitlezen met:
Heb je gecontroleerd of ID niet toevallig hetzelfde is voor alle InvoiceLines? Dat zou verklaren waarom je array maar één entry heeft (dezelfde index wordt telkens overschreven).
De betekenis is mij niet direct duidelijk, maar als je een unieke index nodig hebt is OrderLineReference.LineID misschien een betere kandidaat, of zijn dit nummers uit verschillende systemen?