Reputation: 349
Hi everyone I have this XML structure and I would like to get the value of the IdDocumento
attributes
<pago10:Pagos>
<pago10:Pago>
<pago10:DoctoRelacionado IdDocumento="B670AD5D-8BA6-42CF-A0D0-1A403E042FBA" />
</pago10:Pago>
<pago10:Pago>
<pago10:DoctoRelacionado IdDocumento="B670AD5D-8BA6-42CF-A0D0-1A403E042FBA" />
<pago10:DoctoRelacionado IdDocumento="842b32ce-44c1-4b31-96b8-3a34569c698c" />
</pago10:Pago>
</pago10:Pagos>
I have tried with this as follow:
$xml = simplexml_load_file('complemento.xml');
$ns = $xml->getNamespaces(true);
$xml->registerXPathNamespace('p', $ns['pago10']);
if ($xml->xpath('//p:Pagos')) {
foreach ($xml->xpath('//p:Pagos') as $pagos10) {
foreach ($xml->xpath('//p:Pago') as $pago10) {
foreach ($xml->xpath('//p:DoctoRelacionado') as $doc) {
echo $doc['IdDocumento'] . '<br>';
}
echo "=========================================";
}
}
}
But this is displaying the 3 attributes IdDocumento
at once I was hoping to print the first
attribute IdDocumento
and make the separator and then print the other two, how can I know which
IdDocumento belongs to every pago10:Pago
node?
Expected result:
B670AD5D-8BA6-42CF-A0D0-1A403E042FB
====================================
B670AD5D-8BA6-42CF-A0D0-1A403E042FBA
842b32ce-44c1-4b31-96b8-3a34569c698c
What I'm getting:
B670AD5D-8BA6-42CF-A0D0-1A403E042FB
B670AD5D-8BA6-42CF-A0D0-1A403E042FBA
842b32ce-44c1-4b31-96b8-3a34569c698c
====================================
B670AD5D-8BA6-42CF-A0D0-1A403E042FB
B670AD5D-8BA6-42CF-A0D0-1A403E042FBA
842b32ce-44c1-4b31-96b8-3a34569c698c
Upvotes: 0
Views: 96
Reputation: 1271
The issue is with your xpath
in that $xml->xpath('//p:DoctoRelacionado')
will get all items with DoctoRelacionado
, not just the ones inside the current Pago
.
Instead, only the first foreach
should use xpath and the others should use something like the children()
method of SimpleXMLElement
.
To fix this, try switching your foreach
statements for the below:
foreach ($xml->xpath('//p:Pagos') as $pagos10) {
foreach ($pagos10->children() as $pago10) {
foreach ($pago10->children() as $doc) {
echo $doc['IdDocumento'] . '<br>';
}
echo "=========================================<br>";
}
}
Upvotes: 2
Reputation: 57131
One of the problems was the way you were always using $xml
as the start point for the XPath, so this was always going back to the top level of the document to find the next layer of elements. In this code it uses the element from the previous foreach()
as the start point.
Also note that it uses the descendant axis ('descendant::
) so that this only uses elements which are under the start point.
$ns = $xml->getNamespaces(true);
$xml->registerXPathNamespace('pago10', $ns['pago10']);
if ($xml->xpath('//pago10:Pagos')) {
foreach ($xml->xpath('//pago10:Pagos') as $pagos10) {
foreach ($pagos10->xpath('descendant::pago10:Pago') as $pago10) {
foreach ($pago10->xpath('descendant::pago10:DoctoRelacionado') as $doc) {
echo $doc['IdDocumento'] . '<br>';
}
echo "=========================================".PHP_EOL;
}
}
}
Upvotes: 2