Как объединить два XML-документа в PHP, используя SimpleXML? - PullRequest
5 голосов
/ 16 декабря 2010

У меня есть строка базы данных, которая выглядит следующим образом.

ID (int):       123
Name (string):  SomeName
Data (string):  <data><foo>one</foo></bar>two</bar></data>

Мне нужно отформатировать эти данные в формате XML следующим образом.

<row>
  <id>123</id>
  <name>SomeName</name>
  <data>
    <foo>one</foo>
    <bar>two</bar>
  </data>
<row>

В настоящее время я использую SimpleXMLчтобы попытаться построить это, но я не уверен, как идти о вставке существующего XML в новый XML-документ, который я пытаюсь построить.

Если есть другие стандартные XML-сборщики, которые приходятс PHP я тоже могу их использовать. Конкатенация строк не является приемлемым ответом.

Редактировать: Похоже, что SimpleXML не будет делать то, что мне нужно.Думаю, на данный момент мне нужны предложения для других анализаторов XML.

Ответы [ 3 ]

2 голосов
/ 16 декабря 2010
$xml = new SimpleXMLElement('<row></row>');
$xml->addChild('id', /*database ID column*/);
$xml->addChild('name', /*database Name column*/);

$data = new SimpleXMLElement(/*database Data column*/);

$xml->addChild('data');
$xml->data->addChild('foo', $data->foo);
$xml->data->addChild('bar', $data->bar);

Проверено и все работает.Преобразовать это в ваше реальное приложение должно быть тривиально.Может быть более гибкий способ сделать это, но я не знаю об этом.Они не зря называют это SimpleXML:)

0 голосов
/ 28 февраля 2014
/**
* Converts your record to XML.
* 
* @param array/object $record
* @return SimpleXMLElement
*/
function ConvertToXml($record){
    // Objects need to be arrays
    if(is_object($record)){
        $record = get_object_vars($record);
    }

    // We need an array argument
    if(!is_array($record)){
        trigger_error('$record must be an object or an array.', E_USER_WARNING);
        return null;
    }

    // Now we build XML
    ob_start();
    echo '<xml>', PHP_EOL;
    foreach($record as $name => $value){
        if(is_object($value) or is_array($value) or is_resource($value)){
            trigger_error('$record must have only scalar values.', E_USER_WARNING);
            return null;
        }
        if(!is_string($name) or !preg_match('~[a-z_][a-z0-9]*~i', $name)){
            trigger_error('$record must have only XML-tag friendly string keys.', E_USER_WARNING);
            return null;
        }

        // NULL produces an empty node
        if(is_null($value)){
            echo "<{$name} />", PHP_EOL;
            continue;
        }

        // Numerics don't need to be XML encoded
        if(is_integer($value) or is_float($value) or is_bool($value)){
            echo "<{$name}>{$value}</{$name}>", PHP_EOL;
            continue;
        }

        // We must have a string now
        if(!is_string($name)){
            trigger_error('$record must have only scalar values.', E_USER_WARNING);
            return null;
        }

        // Do we have an XML field?
        if(preg_match('~^\s*<.+>\s*$~s', $value)){
            // Test it for real!
            if($xml = @simplexml_load_string("<xml>{$value}</xml>")){
                echo $value, PHP_EOL;
                continue;
            }
        }

        // Now output random strings
        echo "<{$name}>", htmlentities($value, ENT_QUOTES, 'utf-8'), "</{$name}>", PHP_EOL;
    }
    echo '</xml>', PHP_EOL;

    // Store built XML
    $xml = ob_get_clean();

    // Load the built XML
    return @simplexml_load_string($xml);;
}

// Prepare an array
$record = array();
$record['ID'] = 1;
$record['Name'] = 'SomeName';
$record['Data'] = '<data><foo>one</foo><bar>two</bar></data>';
if($xml = ConvertToXml($record)){
    echo $xml->asXML();
}

^ Ответ для потомков.

0 голосов
/ 16 декабря 2010
$xml = '<data><foo>one</foo><bar>two</bar></data>'; // your data field

$row = new SimpleXMLElement('<row></row>'); // new row to inject your database fields into
$data = new SimpleXMLElement($xml); // new object from your xml data field

$row->id = '123'; // your id field
$row->name = 'Somename'; // your name field
$row->data->foo = $data->foo; // your foo record from your xml data field
$row->data->bar = $data->bar; // your bar record from your xml data field

$final_xml = $row->saveXML(); // restructure your xml file/string
echo $final_xml; // <?xml version="1.0"?><row><id>123</id><name>Somename</name><data><foo>one</foo><bar>two</bar></data></row>

Протестировал этот код, и он также работает.Вам нужно будет создать два объекта SimpleXml, как в ответе выше.Помимо этого вы можете просто добавить дополнительные элементы, такие как добавление класса Vars.<?xml version="1.0"?> будет добавлено в окончательную строку / файл xml.

Не уверен, если вам нужен <?xml version="1.0"?>.Если нет, вы можете взять его с помощью:

$final_xml = str_replace("<?xml version=\"1.0\"?>\n",'',$final_xml);

Вы можете проверить http://www.php.net/manual/en/simplexmlelement.asxml.php для получения дополнительной информации о повторном сохранении объектов SimpleXml обратно в строки / файлы XML.

...