Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/eclipxe13/CfdiUtils/llms.txt

Use this file to discover all available pages before exploring further.

QuickReader is a lightweight, read-only view over a CFDI document designed for speed and convenience. It strips XML namespace prefixes and treats all element and attribute names as case-insensitive, so you can navigate a CFDI without memorising exact casing or namespace qualifiers. It is the right choice when you need to extract data quickly — for example, when exporting fields to a JSON structure or populating a PDF template.
QuickReader is a lossy transformation. Namespace information is discarded, and case distinctions are lost. It cannot read text nodes or XML comments. For full-fidelity access — or when you need to write or validate the document — use the Cfdi class and its NodeInterface tree instead.

Get the QuickReader

Call getQuickReader() on any Cfdi object. The returned QuickReader instance represents the root cfdi:Comprobante element.
<?php
// Create the Cfdi object
$cfdi = \CfdiUtils\Cfdi::newFromString(
    file_get_contents('cfdi.xml')
);

// Obtain the QuickReader for the root Comprobante element
$comprobante = $cfdi->getQuickReader();

Access Attributes

Use array notation (square brackets) to read attribute values. Attribute lookup is case-insensitive, so version, Version, and vErSiOn all return the same value. Calling offsetGet on a missing attribute returns an empty string — no exception is thrown. Use isset() to check whether an attribute is actually present.
<?php
$comprobante = \CfdiUtils\Cfdi::newFromString(file_get_contents('cfdi.xml'))
    ->getQuickReader();

echo $comprobante['version'];  // (string) "4.0"
echo $comprobante['Version'];  // (string) "4.0"
echo $comprobante['vErSiOn'];  // (string) "4.0"

var_dump(isset($comprobante['version']));    // (bool) true
var_dump(isset($comprobante['no-existe'])); // (bool) false
var_dump($comprobante['no-existe']);         // (string) ""

Get All Attributes

Call getAttributes() to retrieve the full attribute map as an associative array. Keys are stored with their original casing from the XML source.
<?php
var_dump($comprobante->getAttributes());
/*
    array(1) {
      ["Version"]=>
      string(3) "4.0"
    }
*/

Access Child Elements

Use property notation (arrow syntax) to navigate to a child element by name. The lookup is case-insensitive and returns the first matching child as a new QuickReader instance. If no matching child exists, a QuickReader bearing the same name as the property you accessed is returned (with no attributes or children) — navigation never throws. Use isset() to test whether a child actually exists.
<?php
$comprobante = \CfdiUtils\Cfdi::newFromString(file_get_contents('cfdi.xml'))
    ->getQuickReader();

/*
 * <cfdi:Comprobante ...>
 *     <cfdi:Impuestos TotalImpuestosTrasladados="123.45">...</cfdi:Impuestos>
 * </cfdi:Comprobante>
 */
echo $comprobante->impuestos['totalImpuestosTrasladados']; // (string) "123.45"

/*
 * <cfdi:Comprobante ...>
 *     <cfdi:Complemento>
 *         <tfd:TimbreFiscalDigital FechaTimbrado="2017-03-21T08:18:08" ... />
 *     </cfdi:Complemento>
 * </cfdi:Comprobante>
 */
echo $comprobante->complemento->timbreFiscalDigital['fechatimbrado']; // 2017-03-21T08:18:08

// Non-existent paths never throw — they just return empty strings
var_dump(isset($comprobante->foo));          // (bool) false
echo $comprobante->foo->bar->baz->xee['info']; // (string) ""

Access Multiple Children

To retrieve all children of a node, call the QuickReader object as if it were a function. The invocation returns an array of QuickReader instances.
<?php
$comprobante = \CfdiUtils\Cfdi::newFromString(file_get_contents('cfdi.xml'))
    ->getQuickReader();

// $hijos is an array of QuickReader objects
$hijos = $comprobante();

foreach ($hijos as $hijo) {
    echo $hijo; // Emisor, Receptor, Conceptos, Impuestos, etc.
}
You can also call getChildren(string $name = '') as an explicit alias. Passing a name filters the results to children with that name (case-insensitive).

Iterating Nested Children

Because $comprobante->conceptos() is interpreted by PHP as a method call on $comprobante, you must either assign the property to a variable first or wrap it in parentheses before invoking it.
<?php
$comprobante = \CfdiUtils\Cfdi::newFromString(file_get_contents('cfdi.xml'))
    ->getQuickReader();

$conceptos = $comprobante->conceptos;
foreach ($conceptos() as $concepto) {
    $traslados = $concepto->impuestos->traslados;
    foreach ($traslados() as $traslado) {
        echo $traslado['impuesto'];
    }
}

Access Children by Name

Pass a name string to the invocation to retrieve only children whose name matches (case-insensitive).
<?php
$comprobante = \CfdiUtils\Cfdi::newFromString(file_get_contents('cfdi.xml'))
    ->getQuickReader();

// Returns an array containing only children named "concepto"
$hijos = ($comprobante->conceptos)('concepto');

Node Name

In the rare case that you need the name of a node, cast it to string:
<?php
$comprobante = \CfdiUtils\Cfdi::newFromString(file_get_contents('cfdi.xml'))
    ->getQuickReader();

echo (string) $comprobante; // (string) "Comprobante"

Limitations

QuickReader is intentionally narrow in scope. Keep these constraints in mind:
  • Lossy — XML namespace prefixes are stripped. Two elements from different namespaces but with the same local name are indistinguishable.
  • Case-insensitive — original attribute and element casing is not preserved during lookup.
  • Read-only — any attempt to set an attribute or child element throws a \LogicException. The object is immutable by design.
  • No text nodes or comments — only XML elements and their attributes are imported; text content and XML comments are ignored.

When to Use QuickReader vs Cfdi

ScenarioRecommended API
Export CFDI fields to JSON or a databaseQuickReader
Populate a PDF or HTML templateQuickReader
Navigate with exact namespace and attribute namesCfdi + NodeInterface
Validate a CFDI documentCfdi + validator classes
Programmatic modification of the XML treeCfdi + NodeInterface
Both APIs are available on the same Cfdi instance — call getNode() for the full NodeInterface tree or getQuickReader() for the simplified view, whichever suits the task at hand.

Build docs developers (and LLMs) love