如何使用SimpleXML在PHP中合并两个XML文档?

时间:2022-10-27 07:29:57

I have a database row that looks like this.

我有一个看起来像这样的数据库行。

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

I need to format this data as XML in the following way.

我需要以下列方式将此数据格式化为XML。

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

I'm currently using SimpleXML to try to build this, but I'm not sure how to go about inserting the existing XML into the new XML document I'm trying to build.

我目前正在使用SimpleXML来尝试构建它,但我不确定如何将现有的XML插入到我正在尝试构建的新XML文档中。

If there are other standard XML builders that come with PHP, I'm open to using those, too. String concatenation is not an acceptable answer.

如果PHP附带其他标准XML构建器,我也可以使用它们。字符串连接不是可接受的答案。

Edit: It looks as though SimpleXML won't do what I need. I guess at this point, I need suggestions for other XML parsers.

编辑:看起来好像SimpleXML不会做我需要的。我想在这一点上,我需要其他XML解析器的建议。

3 个解决方案

#1


2  

$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);

Tested and it works. It should be trivial to convert this to your actual application. There may be a more flexible way of doing it, but I'm not aware of it. They don't call it SimpleXML for nothing :)

经过测试,确实有效。将此转换为您的实际应用程序应该是微不足道的。可能有一种更灵活的方式,但我不知道。他们没有把它称为SimpleXML :)

#2


0  

$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>

Tested this code and it also works. You will have to create two SimpleXml Objects like the answer above. Other than that you can just add additional elements like adding class vars. A <?xml version="1.0"?> will be added to the final xml string/file.

测试了这段代码,它也有效。你必须创建两个SimpleXml对象,如上面的答案。除此之外,您可以添加其他元素,如添加类变量。 <?xml version =“1.0”?>将添加到最终的xml字符串/文件中。

Not sure if you need the <?xml version="1.0"?>. If not you can take it out with:

不确定是否需要<?xml version =“1.0”?>。如果没有,你可以把它拿出来:

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

You can check out http://www.php.net/manual/en/simplexmlelement.asxml.php for more info on re-saving SimpleXml objects back to xml strings/files.

您可以查看http://www.php.net/manual/en/simplexmlelement.asxml.php,了解有关将SimpleXml对象重新保存回xml字符串/文件的更多信息。

#3


0  

/**
* 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();
}

^ An answer for posterity.

^后代的答案。

#1


2  

$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);

Tested and it works. It should be trivial to convert this to your actual application. There may be a more flexible way of doing it, but I'm not aware of it. They don't call it SimpleXML for nothing :)

经过测试,确实有效。将此转换为您的实际应用程序应该是微不足道的。可能有一种更灵活的方式,但我不知道。他们没有把它称为SimpleXML :)

#2


0  

$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>

Tested this code and it also works. You will have to create two SimpleXml Objects like the answer above. Other than that you can just add additional elements like adding class vars. A <?xml version="1.0"?> will be added to the final xml string/file.

测试了这段代码,它也有效。你必须创建两个SimpleXml对象,如上面的答案。除此之外,您可以添加其他元素,如添加类变量。 <?xml version =“1.0”?>将添加到最终的xml字符串/文件中。

Not sure if you need the <?xml version="1.0"?>. If not you can take it out with:

不确定是否需要<?xml version =“1.0”?>。如果没有,你可以把它拿出来:

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

You can check out http://www.php.net/manual/en/simplexmlelement.asxml.php for more info on re-saving SimpleXml objects back to xml strings/files.

您可以查看http://www.php.net/manual/en/simplexmlelement.asxml.php,了解有关将SimpleXml对象重新保存回xml字符串/文件的更多信息。

#3


0  

/**
* 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();
}

^ An answer for posterity.

^后代的答案。