XML conversion
The XMLConverter
converts a CSV records collection into a PHP DOMDocument
.
Settings
Prior to converting your records collection into XML, you may wish to configure the element and its associated attribute names. To do so, XMLConverter
provides methods to set up these settings.
XMLConverter::rootElement
public XMLConverter::rootElement(string $node_name): self
This method sets the XML root name.
XMLConverter::recordElement
public XMLConverter::recordElement(string $node_name, string $record_offset_attribute_name = ''): self
This method sets the XML record name and optionally the attribute name for the record offset value if you want this information preserved.
XMLConverter::fieldElement
public XMLConverter::fieldElement(string $node_name, string $fieldname_attribute_name = ''): self
This method sets the XML field name and optionally the attribute name for the field name value.
Conversion
public XMLConverter::convert(iterable $records): DOMDocument
The XMLConverter::convert
accepts an iterable
which represents the records collection and returns a DOMDocument
object.
use League\Csv\XMLConverter;
use League\Csv\Statement;
use League\Csv\Reader;
$csv = Reader::createFromPath('/path/to/prenoms.csv', 'r');
$csv->setDelimiter(';');
$csv->setHeaderOffset(0);
$stmt = (new Statement())
->where(function (array $record) {
return 'Anaïs' === $record['prenoms'];
})
->offset(0)
->limit(2)
;
$converter = (new XMLConverter())
->rootElement('csv')
->recordElement('record', 'offset')
->fieldElement('field', 'name')
;
$records = $stmt->process($csv);
$dom = $converter->convert($records);
$dom->formatOutput = true;
$dom->encoding = 'iso-8859-15';
echo '<pre>', PHP_EOL;
echo htmlentities($dom->saveXML());
// <?xml version="1.0" encoding="iso-8859-15"?>
// <csv>
// <record offset="71">
// <field name="prenoms">Anaïs</field>
// <field name="nombre">137</field>
// <field name="sexe">F</field>
// <field name="annee">2004</field>
// </record>
// <record offset="1099">
// <field name="prenoms">Anaïs</field>
// <field name="nombre">124</field>
// <field name="sexe">F</field>
// <field name="annee">2005</field>
// </record>
// </csv>
Import
public XMLConverter::import(iterable $records, DOMDocument $doc): DOMElement
Instead of converting your tabular data into a full XML document you can now import it into an already existing DOMDocument
object.
To do so, you need to specify which document the data should be imported into using the XMLConverter::import
method.
This method takes two arguments:
- the tabular data as defined for the
XMLConverter::convert
method; - a
DOMDocument
object to import the data into;
Note that the resulting DOMElement
is attached to the given DOMDocument
object but not yet included in the document tree.
To include it, you still need to call a DOM insertion method like appendChild
or insertBefore
with a node that is currently in the document tree.
use League\Csv\XMLConverter;
use League\Csv\Statement;
use League\Csv\Reader;
$csv = Reader::createFromPath('/path/to/prenoms.csv', 'r');
$csv->setDelimiter(';');
$csv->setHeaderOffset(0);
$stmt = (new Statement())
->where(function (array $record) {
return 'Anaïs' === $record['prenoms'];
})
->offset(0)
->limit(2)
;
$converter = (new XMLConverter())
->rootElement('csv')
->recordElement('record', 'offset')
->fieldElement('field', 'name')
;
$records = $stmt->process($csv);
$dom = new DOMDocument('1.0');
$dom->loadXML('<root><header><name>My CSV Document</name></header></root>');
$data = $converter->import($records, $dom);
$dom->appendChild($data);
$dom->formatOutput = true;
$dom->encoding = 'iso-8859-15';
echo '<pre>', PHP_EOL;
echo htmlentities($dom->saveXML());
// <?xml version="1.0" encoding="iso-8859-15"?>
// <root>
// <header>
// <name>My CSV Document</name>
// </header>
// <csv>
// <record offset="71">
// <field name="prenoms">Anaïs</field>
// <field name="nombre">137</field>
// <field name="sexe">F</field>
// <field name="annee">2004</field>
// </record>
// <record offset="1099">
// <field name="prenoms">Anaïs</field>
// <field name="nombre">124</field>
// <field name="sexe">F</field>
// <field name="annee">2005</field>
// </record>
// </csv>
// </root>
Download
To download the generated JSON you can use the XMLConverter::download
method. The method returns
the total number of bytes sent just like the XMLConverter::save
method and enable downloading the XML on the fly.
General purpose
use League\Csv\Reader;
use League\Csv\JsonConverter;
$reader = Reader::createFromPath('file.csv');
$reader->setHeaderOffset(0);
header('Cache-Control: no-cache, no-store, must-revalidate');
header('Pragma: no-cache');
header('Expires: 0');
header('Content-Type: text/xml; charset=UTF-8');
header('Content-Description: File Transfer');
header('Content-Disposition: attachment; filename="name-for-your-file.xml"');
XMLConverter::create()->download($reader);
die;
In this scenario, you have to specify all the headers for the file to be downloaded.
Using a filename
To download the generated XML on the fly you can use the XMLConverter::download
method:
use League\Csv\Reader;
use League\Csv\XMLConverter;
$reader = Reader::createFromPath('file.csv');
$reader->setHeaderOffset(0);
header('Cache-Control: no-cache, no-store, must-revalidate');
header('Pragma: no-cache');
header('Expires: 0');
//the filename will be the name of the downloaded xml as shown by your HTTP client!
XMLConverter::create()->download($reader, 'name-for-your-file.xml');
die;
By default, the method will set the encoding to utf-8
and will not format the XML. You can set those values using
the method optional arguments.
use League\Csv\Reader;
use League\Csv\XMLConverter;
$reader = Reader::createFromPath('file.csv');
$reader->setHeaderOffset(0);
header('Cache-Control: no-cache, no-store, must-revalidate');
header('Pragma: no-cache');
header('Expires: 0');
XMLConverter::create()->download(
records: $reader,
filename: 'generated_file.xml',
encoding: 'iso-8859-1',
formatOutput: true,
);
die;