-
-
Save goedecke/03e9c7c178ff947b1e9d9eaea4bbe369 to your computer and use it in GitHub Desktop.
<?php | |
$xml = simplexml_load_file('test.xml'); | |
$ns = $xml->getNamespaces(true); | |
$xml->registerXPathNamespace('c', $ns['cfdi']); | |
$xml->registerXPathNamespace('t', $ns['tfd']); | |
//EMPIEZO A LEER LA INFORMACION DEL CFDI E IMPRIMIRLA | |
foreach ($xml->xpath('//cfdi:Comprobante') as $cfdiComprobante){ | |
echo $cfdiComprobante['version']; | |
echo "<br />"; | |
echo $cfdiComprobante['fecha']; | |
echo "<br />"; | |
echo $cfdiComprobante['sello']; | |
echo "<br />"; | |
echo $cfdiComprobante['total']; | |
echo "<br />"; | |
echo $cfdiComprobante['subTotal']; | |
echo "<br />"; | |
echo $cfdiComprobante['certificado']; | |
echo "<br />"; | |
echo $cfdiComprobante['formaDePago']; | |
echo "<br />"; | |
echo $cfdiComprobante['noCertificado']; | |
echo "<br />"; | |
echo $cfdiComprobante['tipoDeComprobante']; | |
echo "<br />"; | |
} | |
foreach ($xml->xpath('//cfdi:Comprobante//cfdi:Emisor') as $Emisor){ | |
echo $Emisor['rfc']; | |
echo "<br />"; | |
echo $Emisor['nombre']; | |
echo "<br />"; | |
} | |
foreach ($xml->xpath('//cfdi:Comprobante//cfdi:Emisor//cfdi:DomicilioFiscal') as $DomicilioFiscal){ | |
echo $DomicilioFiscal['pais']; | |
echo "<br />"; | |
echo $DomicilioFiscal['calle']; | |
echo "<br />"; | |
echo $DomicilioFiscal['estado']; | |
echo "<br />"; | |
echo $DomicilioFiscal['colonia']; | |
echo "<br />"; | |
echo $DomicilioFiscal['municipio']; | |
echo "<br />"; | |
echo $DomicilioFiscal['noExterior']; | |
echo "<br />"; | |
echo $DomicilioFiscal['codigoPostal']; | |
echo "<br />"; | |
} | |
foreach ($xml->xpath('//cfdi:Comprobante//cfdi:Emisor//cfdi:ExpedidoEn') as $ExpedidoEn){ | |
echo $ExpedidoEn['pais']; | |
echo "<br />"; | |
echo $ExpedidoEn['calle']; | |
echo "<br />"; | |
echo $ExpedidoEn['estado']; | |
echo "<br />"; | |
echo $ExpedidoEn['colonia']; | |
echo "<br />"; | |
echo $ExpedidoEn['noExterior']; | |
echo "<br />"; | |
echo $ExpedidoEn['codigoPostal']; | |
echo "<br />"; | |
} | |
foreach ($xml->xpath('//cfdi:Comprobante//cfdi:Receptor') as $Receptor){ | |
echo $Receptor['rfc']; | |
echo "<br />"; | |
echo $Receptor['nombre']; | |
echo "<br />"; | |
} | |
foreach ($xml->xpath('//cfdi:Comprobante//cfdi:Receptor//cfdi:Domicilio') as $ReceptorDomicilio){ | |
echo $ReceptorDomicilio['pais']; | |
echo "<br />"; | |
echo $ReceptorDomicilio['calle']; | |
echo "<br />"; | |
echo $ReceptorDomicilio['estado']; | |
echo "<br />"; | |
echo $ReceptorDomicilio['colonia']; | |
echo "<br />"; | |
echo $ReceptorDomicilio['municipio']; | |
echo "<br />"; | |
echo $ReceptorDomicilio['noExterior']; | |
echo "<br />"; | |
echo $ReceptorDomicilio['noInterior']; | |
echo "<br />"; | |
echo $ReceptorDomicilio['codigoPostal']; | |
echo "<br />"; | |
} | |
foreach ($xml->xpath('//cfdi:Comprobante//cfdi:Conceptos//cfdi:Concepto') as $Concepto){ | |
echo "<br />"; | |
echo $Concepto['unidad']; | |
echo "<br />"; | |
echo $Concepto['importe']; | |
echo "<br />"; | |
echo $Concepto['cantidad']; | |
echo "<br />"; | |
echo $Concepto['descripcion']; | |
echo "<br />"; | |
echo $Concepto['valorUnitario']; | |
echo "<br />"; | |
echo "<br />"; | |
} | |
foreach ($xml->xpath('//cfdi:Comprobante//cfdi:Impuestos//cfdi:Traslados//cfdi:Traslado') as $Traslado){ | |
echo $Traslado['tasa']; | |
echo "<br />"; | |
echo $Traslado['importe']; | |
echo "<br />"; | |
echo $Traslado['impuesto']; | |
echo "<br />"; | |
echo "<br />"; | |
} | |
//ESTA ULTIMA PARTE ES LA QUE GENERABA EL ERROR | |
foreach ($xml->xpath('//t:TimbreFiscalDigital') as $tfd) { | |
echo $tfd['selloCFD']; | |
echo "<br />"; | |
echo $tfd['FechaTimbrado']; | |
echo "<br />"; | |
echo $tfd['UUID']; | |
echo "<br />"; | |
echo $tfd['noCertificadoSAT']; | |
echo "<br />"; | |
echo $tfd['version']; | |
echo "<br />"; | |
echo $tfd['selloSAT']; | |
} | |
?> |
Me faltó felicitarte goedecke... excelente código.. muy sencillo de implementar y entender...!!! Gracias nuevamente..
Se corrigió con un cast a array
Código anterior:
$attributes = array_merge(
$attributes,
current($XMLNode->attributes())
);
Código nuevo:
$attributes = array_merge(
$attributes,
(array)current($XMLNode->attributes())
);Gracias nuevamente por la aportación..
Vale, haré el cambio.. la realidad es que no lo pasé por stan para hacer un análisis del código (amén de las pruebas unitarias/funcionales), gracias por la retro.
para los que necesiten leer dentro de Complementos en facturas P
// verifica que sea P y obtiene el monto if($tipocomprobante == 'P') { foreach ($xml->xpath('//cfdi:Comprobante//cfdi:Complemento//pago10:Pagos//pago10:Pago') as $Pago10){ $montop = $Pago10['Monto']; //drupal_set_message('monto: '.$montop, 'status', FALSE); $node->field_factura_pago10_monto['und'][0]['value'] = $montop; } }
EDIT: este codigo esta mas limpio
` // verifica que sea P y obtiene el monto if($tipocomprobante == 'P') { $xml->registerXPathNamespace('p', $ns['pago10']); // set monto pago 10 foreach ($xml->xpath('//p:Pago') as $pago10) { $montop = $pago10['Monto']; $node->field_factura_pago10_monto['und'][0]['value'] = $montop; } // set id ducumentp rel $documentosRel = $xml->xpath('//p:DoctoRelacionado'); foreach ($documentosRel as $key) { $node->field_pago_10_doctorel_id_dcto['und'][0]['value'] = $key['IdDocumento']; } } // fin comprobante P`
para los que necesiten leer dentro de Complementos en facturas P
// verifica que sea P y obtiene el monto if($tipocomprobante == 'P') { foreach ($xml->xpath('//cfdi:Comprobante//cfdi:Complemento//pago10:Pagos//pago10:Pago') as $Pago10){ $montop = $Pago10['Monto']; //drupal_set_message('monto: '.$montop, 'status', FALSE); $node->field_factura_pago10_monto['und'][0]['value'] = $montop; } }
EDIT: este codigo esta mas limpio
` // verifica que sea P y obtiene el monto if($tipocomprobante == 'P') { $xml->registerXPathNamespace('p', $ns['pago10']); // set monto pago 10 foreach ($xml->xpath('//p:Pago') as $pago10) { $montop = $pago10['Monto']; $node->field_factura_pago10_monto['und'][0]['value'] = $montop; } // set id ducumentp rel $documentosRel = $xml->xpath('//p:DoctoRelacionado'); foreach ($documentosRel as $key) { $node->field_pago_10_doctorel_id_dcto['und'][0]['value'] = $key['IdDocumento']; } } // fin comprobante P`
Hola. Estoy recibiendo varios complementos que tienen dos o más pagos y cada pago a su vez tiene sus Documentos relacionados. ¿Cómo puedo leer el complemento de manera que pueda ver qué Documentos relacionados están amparados con cada Pago o monto? Por ejemplo:
cfdi:Complemento
<pago10:Pagos Version="1.0">
<pago10:Pago FechaPago="2019-06-21T12:07:57" FormaDePagoP="03" MonedaP="MXN" Monto="150000.00 ">
<pago10:DoctoRelacionado IdDocumento="UUID1" Serie="PC" Folio="230156" MonedaDR="MXN" MetodoDePagoDR="PPD" NumParcialidad="1 " ImpSaldoAnt="75000.00 " ImpPagado="75000.00 " ImpSaldoInsoluto="0.00 "/>
<pago10:DoctoRelacionado IdDocumento="UUID2" Serie="PC" Folio="230160" MonedaDR="MXN" MetodoDePagoDR="PPD" NumParcialidad="1 " ImpSaldoAnt="75000.00 " ImpPagado="750000.00 " ImpSaldoInsoluto="0.00 "/>
</pago10:Pago>
<pago10:Pago FechaPago="2019-06-21T14:35:25" FormaDePagoP="03" MonedaP="MXN" Monto="100000.00 ">
<pago10:DoctoRelacionado IdDocumento="UUID3" Serie="PC" Folio="230181" MonedaDR="MXN" MetodoDePagoDR="PPD" NumParcialidad="1 " ImpSaldoAnt="20000.00 " ImpPagado="20000.00 " ImpSaldoInsoluto="0.00 "/>
<pago10:DoctoRelacionado IdDocumento="UUID4" Serie="PC" Folio="230236" MonedaDR="MXN" MetodoDePagoDR="PPD" NumParcialidad="1 " ImpSaldoAnt="30000.00 " ImpPagado="30000.00 " ImpSaldoInsoluto="0.00 "/>
<pago10:DoctoRelacionado IdDocumento="UUID5" Serie="PC" Folio="230238" MonedaDR="MXN" MetodoDePagoDR="PPD" NumParcialidad="1 " ImpSaldoAnt="50000.00 " ImpPagado="50000.00 " ImpSaldoInsoluto="0.00 "/>
</pago10:Pago>
</pago10:Pagos>
De esto quisiera obtener algo como
Pago 1 - Monto 150000 - UUID1 - UUID2
Pago 2 - Monto 100000 - UUID3 - UUID4 - UUID5
¿Es posible hacerlo con ese orden?
Porque lo que consigo es
Pago 1 - Monto
Pago 2- Monto
UUID1
UUID2
UUID3
UUID4
UUID5
Buenas tardes, estaba accediendo a las facturas pero hoy me genero este error y no encuentro el porque surge, si alguien pudiera dar un poco de ayuda lo agradeceria.
This page contains the following errors:
error on line 28 at column 182: xmlns:schemaLocation: 'http://www.sat.gob.mx/registrofiscal http://www.sat.gob.mx/sitio_internet/cfd/cfdiregistrofiscal/cfdiregistrofiscal.xsd' is not a valid URI
Below is a rendering of the page up to the first error.
Buenas tardes, estaba accediendo a las facturas pero hoy me genero este error y no encuentro el porque surge, si alguien pudiera dar un poco de ayuda lo agradeceria.
This page contains the following errors:
error on line 28 at column 182: xmlns:schemaLocation: 'http://www.sat.gob.mx/registrofiscal http://www.sat.gob.mx/sitio_internet/cfd/cfdiregistrofiscal/cfdiregistrofiscal.xsd' is not a valid URI
Below is a rendering of the page up to the first error.
¿tienes más información al respecto?
¿dónde se presenta el error, factura de ejemplo...?
para los que necesiten leer dentro de Complementos en facturas P
// verifica que sea P y obtiene el monto if($tipocomprobante == 'P') { foreach ($xml->xpath('//cfdi:Comprobante//cfdi:Complemento//pago10:Pagos//pago10:Pago') as $Pago10){ $montop = $Pago10['Monto']; //drupal_set_message('monto: '.$montop, 'status', FALSE); $node->field_factura_pago10_monto['und'][0]['value'] = $montop; } }
EDIT: este codigo esta mas limpio
` // verifica que sea P y obtiene el monto if($tipocomprobante == 'P') { $xml->registerXPathNamespace('p', $ns['pago10']); // set monto pago 10 foreach ($xml->xpath('//p:Pago') as $pago10) { $montop = $pago10['Monto']; $node->field_factura_pago10_monto['und'][0]['value'] = $montop; } // set id ducumentp rel $documentosRel = $xml->xpath('//p:DoctoRelacionado'); foreach ($documentosRel as $key) { $node->field_pago_10_doctorel_id_dcto['und'][0]['value'] = $key['IdDocumento']; } } // fin comprobante P`
para los que necesiten leer dentro de Complementos en facturas P
// verifica que sea P y obtiene el monto if($tipocomprobante == 'P') { foreach ($xml->xpath('//cfdi:Comprobante//cfdi:Complemento//pago10:Pagos//pago10:Pago') as $Pago10){ $montop = $Pago10['Monto']; //drupal_set_message('monto: '.$montop, 'status', FALSE); $node->field_factura_pago10_monto['und'][0]['value'] = $montop; } }
EDIT: este codigo esta mas limpio
` // verifica que sea P y obtiene el monto if($tipocomprobante == 'P') { $xml->registerXPathNamespace('p', $ns['pago10']); // set monto pago 10 foreach ($xml->xpath('//p:Pago') as $pago10) { $montop = $pago10['Monto']; $node->field_factura_pago10_monto['und'][0]['value'] = $montop; } // set id ducumentp rel $documentosRel = $xml->xpath('//p:DoctoRelacionado'); foreach ($documentosRel as $key) { $node->field_pago_10_doctorel_id_dcto['und'][0]['value'] = $key['IdDocumento']; } } // fin comprobante P`
Hola. Estoy recibiendo varios complementos que tienen dos o más pagos y cada pago a su vez tiene sus Documentos relacionados. ¿Cómo puedo leer el complemento de manera que pueda ver qué Documentos relacionados están amparados con cada Pago o monto? Por ejemplo:
cfdi:Complemento <pago10:Pagos Version="1.0"> <pago10:Pago FechaPago="2019-06-21T12:07:57" FormaDePagoP="03" MonedaP="MXN" Monto="150000.00 "> <pago10:DoctoRelacionado IdDocumento="UUID1" Serie="PC" Folio="230156" MonedaDR="MXN" MetodoDePagoDR="PPD" NumParcialidad="1 " ImpSaldoAnt="75000.00 " ImpPagado="75000.00 " ImpSaldoInsoluto="0.00 "/> <pago10:DoctoRelacionado IdDocumento="UUID2" Serie="PC" Folio="230160" MonedaDR="MXN" MetodoDePagoDR="PPD" NumParcialidad="1 " ImpSaldoAnt="75000.00 " ImpPagado="750000.00 " ImpSaldoInsoluto="0.00 "/> </pago10:Pago> <pago10:Pago FechaPago="2019-06-21T14:35:25" FormaDePagoP="03" MonedaP="MXN" Monto="100000.00 "> <pago10:DoctoRelacionado IdDocumento="UUID3" Serie="PC" Folio="230181" MonedaDR="MXN" MetodoDePagoDR="PPD" NumParcialidad="1 " ImpSaldoAnt="20000.00 " ImpPagado="20000.00 " ImpSaldoInsoluto="0.00 "/> <pago10:DoctoRelacionado IdDocumento="UUID4" Serie="PC" Folio="230236" MonedaDR="MXN" MetodoDePagoDR="PPD" NumParcialidad="1 " ImpSaldoAnt="30000.00 " ImpPagado="30000.00 " ImpSaldoInsoluto="0.00 "/> <pago10:DoctoRelacionado IdDocumento="UUID5" Serie="PC" Folio="230238" MonedaDR="MXN" MetodoDePagoDR="PPD" NumParcialidad="1 " ImpSaldoAnt="50000.00 " ImpPagado="50000.00 " ImpSaldoInsoluto="0.00 "/> </pago10:Pago> </pago10:Pagos>
De esto quisiera obtener algo como
Pago 1 - Monto 150000 - UUID1 - UUID2
Pago 2 - Monto 100000 - UUID3 - UUID4 - UUID5¿Es posible hacerlo con ese orden?
Porque lo que consigo es
Pago 1 - Monto
Pago 2- MontoUUID1
UUID2
UUID3
UUID4
UUID5
Quizás algo así?
foreach ($xml->xpath('//p:Pago') as $pago10) {
$montop = $pago10['Monto'];
$node->field_factura_pago10_monto['und'][0]['value'] = $montop;
// set id ducumentp rel
$documentosRel = $xml->xpath('//p:DoctoRelacionado');
foreach ($documentosRel as $key) {
$node->field_pago_10_doctorel_id_dcto['und'][0]['value'] = $key['IdDocumento'];
}
}
Buenas tardes, estaba accediendo a las facturas pero hoy me genero este error y no encuentro el porque surge, si alguien pudiera dar un poco de ayuda lo agradeceria.
This page contains the following errors:
error on line 28 at column 182: xmlns:schemaLocation: 'http://www.sat.gob.mx/registrofiscal http://www.sat.gob.mx/sitio_internet/cfd/cfdiregistrofiscal/cfdiregistrofiscal.xsd' is not a valid URI
Below is a rendering of the page up to the first error.
Hola viejo tu error es muy simple, tienes dos url en el codigo
'http://www.sat.gob.mx/registrofiscal
y
http://www.sat.gob.mx/sitio_internet/cfd/cfdiregistrofiscal/cfdiregistrofiscal.xsd
Elimina http://www.sat.gob.mx/registrofiscal y con eso debe de funcionar
Buenas tardes, estaba accediendo a las facturas pero hoy me genero este error y no encuentro el porque surge, si alguien pudiera dar un poco de ayuda lo agradeceria.
This page contains the following errors:
error on line 28 at column 182: xmlns:schemaLocation: 'http://www.sat.gob.mx/registrofiscal http://www.sat.gob.mx/sitio_internet/cfd/cfdiregistrofiscal/cfdiregistrofiscal.xsd' is not a valid URI
Below is a rendering of the page up to the first error.Hola viejo tu error es muy simple, tienes dos url en el codigo
'http://www.sat.gob.mx/registrofiscal
y
http://www.sat.gob.mx/sitio_internet/cfd/cfdiregistrofiscal/cfdiregistrofiscal.xsdElimina http://www.sat.gob.mx/registrofiscal y con eso debe de funcionar
Hola hermano, acabo de realizar tu procedimiento y efectivamente eliminando esa linea se puede visualizar la factura, muchas gracias, sabes si hay alguna manera de leer la factura y poder eliminar esa url de manera programada? de ante mano muchas gracias
Buenas, tengo un problemita a la hora de tratar de agregar otro xpath un ejemplo seria este $xml->registerXPathNamespace('n', $ns['nomina12']);
No me detecta lo que vendria siendo la key de nomina12 apesar de que este aparezca en los xml, estoy empezando en esto y se me hace algo confuso, un saludo y muchas gracias
Es posible leer varios archivos desde un input ? eso ya lo hice solamente con un archivo , necesito extraer información de cada uno de ellos para poder hacer un varios análisis de los ingresos y egresos supongo que es con un foreach o sera mejor subir los archivos a una carpeta y leerlos todos ?
Me fue útil para solucionar un problema en especifico con un nodo en la versión 4.0, muchas gracias.
Me fue útil para solucionar un problema en especifico con un nodo en la versión 4.0, muchas gracias.
ejemplo..., cómo fue tu escenario?
foreach ($xml->xpath('//cfdi:Comprobante//cfdi:Impuestos//cfdi:Traslados//cfdi:Traslado') as $traslados) {
$t.= (string)$traslados['TipoFactor'] .'-' .(string)$traslados['TasaOCuota'].(string)$traslados['Importe'].'
';
}
Estoy tratando de leer los traslados dentro de impuestos pero tambien me trae los traslados de los conceptos a pesar de que especifico el xpath...
Buenas! alguna actualizacion para que acepte la version 4 o mayor?
Esto me funciono para extraer el UUID del xml con la version 4.0
$uuid = (string) $xml->xpath('//tfd:TimbreFiscalDigital/@uuid')[0];
Entiendo. Prefiero claridad en la implementación (que sea sencillo para el equipo de trabajo), y lo del consumo de memoria pues es relativo, como bien mencionas; depende del tamaño de documentos a leer (¿facturas de 50Mb?) y lo del # de items a extraer, pues.
En fin, fue solo un aporte que muestra que cada quien tiene una visión distinta para lograr sus objetivos. Saludos.
Estoy de acuerdo con esto, implementé tu solución para un detalle específico que tenía accediendo a atributos anidados, te agradezco el aporte.
Excelente código, funciona de maravilla... Gracias por la aportación.. sólo una observación, en la línea del merge() me mandaba un Warning: Warning: array_key_exists() expects parameter 2 to be array, boolean given in
Se corrigió con un cast a array
Código anterior:
$attributes = array_merge(
$attributes,
current($XMLNode->attributes())
);
Código nuevo:
$attributes = array_merge(
$attributes,
(array)current($XMLNode->attributes())
);
Gracias nuevamente por la aportación..
Saludos.