0

I have this XML:

<?xml version="1.0" encoding="utf-8"?>
<cfdi:Comprobante >
<cfdi:Conceptos>
<cfdi:Concepto cantidad="1.00" unidad="PZA" noIdentificacion="RRGARACION" descripcion="51571 CADENA ORO AMRILLO 45CMTS FAVOR DE SOLDAR EL ESLABON DE LADO DEL BROCHE" valorUnitario="81.90" importe="81.90" />
<cfdi:Concepto cantidad="1.00" unidad="PZA" noIdentificacion="RRGARACION" descripcion="51570 CADENA ORO BLANCO C/CORAZON FAVOR DE SOLDAR A 16 CMTS DEL BROCHE" valorUnitario="206.90" importe="206.90" />
<cfdi:/Conceptos>
<cfdi:Impuestos>
<cfdi:Traslados>
<cfdi:Traslado impuesto="IVA" tasa="16" importe="46.20" />
</cfdi:Traslados>
</cfdi:Impuestos>
</cfdi:Comprobante>

and I need to get the "46.20" value of Traslado / importe. how can I do it? I tried something like this:

$xp = new DOMXpath($xml);
$data['IVA']= getpath("//@Traslados[@impuesto='IVA']/@importe");

but didn't work.

2
  • Have a look at this question more specifically the answers. Your XML is using namespaces (the cfdi: part gives it away). And they need to be handled appropriately. Commented Jun 8, 2017 at 17:33
  • This is not valid XML, the cfdi namespace should be declared with an xmlns attribute. Commented Jun 8, 2017 at 17:39

2 Answers 2

1

There are a couple of corrections to the XML ( adding the name space and moving the / to the start of <cfdi:/Conceptos>.

In the XML, you have to register the namespace in the xpath object so it can work with it and the xpath expression itself is updated...

<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
$xml= <<< XML
<?xml version="1.0" encoding="utf-8"?>
<Comprobante xmlns:cfdi="cfdi">
    <cfdi:Conceptos>
        <cfdi:Concepto cantidad="1.00" unidad="PZA" 
            noIdentificacion="RRGARACION" 
            descripcion="51571 CADENA ORO AMRILLO 45CMTS FAVOR DE SOLDAR EL ESLABON DE LADO DEL BROCHE" valorUnitario="81.90" importe="81.90" />
        <cfdi:Concepto cantidad="1.00" unidad="PZA" 
            noIdentificacion="RRGARACION" 
            descripcion="51570 CADENA ORO BLANCO C/CORAZON FAVOR DE SOLDAR A 16 CMTS DEL BROCHE" valorUnitario="206.90" importe="206.90" />
    </cfdi:Conceptos>
    <cfdi:Impuestos>
        <cfdi:Traslados>
            <cfdi:Traslado impuesto="IVA" tasa="16" importe="46.20" />
        </cfdi:Traslados>
    </cfdi:Impuestos>
</Comprobante>
XML;

$doc = new DOMDocument();
$doc->loadXML($xml);
$xp = new DOMXpath($doc);
$xp->registerNamespace('cfdi', 'cfdi');
print_r( $xp->query("//cfdi:Traslados/*[@impuesto='IVA']/@importe"));
Sign up to request clarification or add additional context in comments.

1 Comment

D'oh! More annoying is that I'd fixed the XPath and not copied it... oh well, main thing is that there is a working answer.
1

So for starters, you're working with invalid XML. It should look something like this:

<?xml version="1.0" encoding="utf-8"?>
<cfdi:Comprobante xmlns:cfdi="https://some/uri">
    <cfdi:Conceptos>
        <cfdi:Concepto cantidad="1.00" unidad="PZA" noIdentificacion="RRGARACION" descripcion="51571 CADENA ORO AMRILLO 45CMTS FAVOR DE SOLDAR EL ESLABON DE LADO DEL BROCHE" valorUnitario="81.90" importe="81.90" />
        <cfdi:Concepto cantidad="1.00" unidad="PZA" noIdentificacion="RRGARACION" descripcion="51570 CADENA ORO BLANCO C/CORAZON FAVOR DE SOLDAR A 16 CMTS DEL BROCHE" valorUnitario="206.90" importe="206.90" />
    </cfdi:Conceptos>
    <cfdi:Impuestos>
        <cfdi:Traslados>
            <cfdi:Traslado impuesto="IVA" tasa="16" importe="46.20" />
        </cfdi:Traslados>
    </cfdi:Impuestos>
</cfdi:Comprobante>

(Note the xmlns attribute and the correct closing slashes.)

Next, you're calling a function getpath which came from where? I don't know. But you're passing it an invalid XPath query. You're looking for the attribute of the Traslados element when you want the Traslado element instead. Try this out:

$xml = <<< XML
<?xml version="1.0" encoding="utf-8"?>
<cfdi:Comprobante xmlns:cfdi="https://some/uri">
    <cfdi:Conceptos>
        <cfdi:Concepto cantidad="1.00" unidad="PZA" noIdentificacion="RRGARACION" descripcion="51571 CADENA ORO AMRILLO 45CMTS FAVOR DE SOLDAR EL ESLABON DE LADO DEL BROCHE" valorUnitario="81.90" importe="81.90" />
        <cfdi:Concepto cantidad="1.00" unidad="PZA" noIdentificacion="RRGARACION" descripcion="51570 CADENA ORO BLANCO C/CORAZON FAVOR DE SOLDAR A 16 CMTS DEL BROCHE" valorUnitario="206.90" importe="206.90" />
    </cfdi:Conceptos>
    <cfdi:Impuestos>
        <cfdi:Traslados>
            <cfdi:Traslado impuesto="IVA" tasa="16" importe="46.20" />
        </cfdi:Traslados>
    </cfdi:Impuestos>
</cfdi:Comprobante>
XML;

$doc = new DomDocument();
$doc->loadXML($xml);
$xp = new DOMXpath($doc);
$xp->registerNamespace("cfdi", "https://some/uri");
$nodes = $xp->query("//cfdi:Traslados/*[@impuesto='IVA']/@importe");
foreach ($nodes as $node) {
    var_dump($node->nodeValue);
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.