Создать динамический XML состоит из n частей - PullRequest
1 голос
/ 29 ноября 2011

Я должен создать XML, как это:

<Flow>
    <Invoice xsi:noNamespaceSchemaLocation="schema.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        /* more stuff */
    </Invoice>
    /*...*/
    <Invoice xsi:noNamespaceSchemaLocation="schema.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        /* more stuff */
    </Invoice>
</Flow>

Вот моя ситуация:

//execute a query with doctrine
$clients = ClientTable::getInstance()->createQuery('c')
    ->addWhere('...stuff...')
    ->execute();

//for every client I have to save certain information about the database
foreach ($clients as $client) {
    /** @var $client Client */
    $values = array();
    $values['client_id'] = $client->id;
    $values['release_date'] = date("Y-m-d");
    //...stuff... 
    $invoice = new Invoice();
    $invoice->create($values);
}

Для каждого цикла тега foreach необходимо сгенерировать тег <Invoice> в xml.

Я бы сделал что-то вроде этого:

$xml = new DOMDocument('1.0', 'utf-8');
$flow = $xml->createElement('Flow');
$xml->appendChild($flow);
foreach ($clients as $client) {
    //...stuff... 
    $invoice = new Invoice();
    $invoice->create($values);
    $invoiceXml = $invoice->createInvoiceXml();
    $flow->appendChild($invoiceXml);
}
$xml->save('flow.xml');

Я попробовал свою идею и понял, что внутри функции createInvoiceXml() мне нужно создать экземпляр нового объекта DOMDocument(), который создаст новую строку <?xml version="1.0" encoding="utf-8"?>, если это неправильно! Тогда я понимаю, что это может быть не лучшим способом, тогда я спрашиваю вас, что?


UPDATE

Я подумал о новом решении:

$xml = new DOMDocument('1.0', 'utf-8');
$flow = $xml->createElement('Flow');
$xml->appendChild($flow);
foreach ($clients as $client) {
    //...stuff... 
    $invoice = new Invoice();
    $invoice->create($values);
    $invoiceXml = $invoice->createInvoiceXml($xml);
    $flow->appendChild($invoiceXml);
}
$xml->save('flow.xml');

а вот и функция createInvoiceXml()

/**
 * @param $xml DOMDocument
 * @return DOMElement
 */
public function createInvoiceXml(&$xml)
{
    $inv = $xml->createElement('Invoice');
    $inv->setAttribute('xsi:noNamespaceSchemaLocation', 'schema.xsd');
    $inv->setAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance');

    $inv->appendChild($xml->createElement('foo'));
    //stuff
    return $inv;
}

Что ты думаешь? Это хорошее решение? С этим решением у меня нет проблем с написанием юнит-теста?

...