Php 从SimpleXMLObject到数组的递归强制转换
我需要递归地将PHP SimpleXMLObject转换为数组。问题是每个子元素也是一个PHP SimpleXMLElementPhp 从SimpleXMLObject到数组的递归强制转换,php,casting,simplexml,Php,Casting,Simplexml,我需要递归地将PHP SimpleXMLObject转换为数组。问题是每个子元素也是一个PHP SimpleXMLElement 这可能吗?没有测试这个,但这似乎可以完成: function convertXmlObjToArr($obj, &$arr) { $children = $obj->children(); foreach ($children as $elementName => $node) { $nextIdx
这可能吗?没有测试这个,但这似乎可以完成:
function convertXmlObjToArr($obj, &$arr)
{
$children = $obj->children();
foreach ($children as $elementName => $node)
{
$nextIdx = count($arr);
$arr[$nextIdx] = array();
$arr[$nextIdx]['@name'] = strtolower((string)$elementName);
$arr[$nextIdx]['@attributes'] = array();
$attributes = $node->attributes();
foreach ($attributes as $attributeName => $attributeValue)
{
$attribName = strtolower(trim((string)$attributeName));
$attribVal = trim((string)$attributeValue);
$arr[$nextIdx]['@attributes'][$attribName] = $attribVal;
}
$text = (string)$node;
$text = trim($text);
if (strlen($text) > 0)
{
$arr[$nextIdx]['@text'] = $text;
}
$arr[$nextIdx]['@children'] = array();
convertXmlObjToArr($node, $arr[$nextIdx]['@children']);
}
return;
}
这是可能的。这是一个递归函数,它打印出父元素的标记和没有子元素的元素的标记+内容。您可以修改它以构建阵列:
foreach( $simpleXmlObject as $element )
{
recurse( $element );
}
function recurse( $parent )
{
echo '<' . $parent->getName() . '>' . "\n";
foreach( $parent->children() as $child )
{
if( count( $child->children() ) > 0 )
{
recurse( $child );
}
else
{
echo'<' . $child->getName() . '>';
echo iconv( 'UTF-8', 'ISO-8859-1', $child );
echo '</' . $child->getName() . '>' . "\n";
}
}
echo'</' . $parent->getName() . '>' . "\n";
}
foreach($simpleXmlObject作为$element)
{
递归($元素);
}
函数递归($parent)
{
回显“”。“\n”;
foreach($parent->children()作为$child)
{
如果(计数($child->children())>0)
{
递归($child);
}
其他的
{
回声';
echo iconv('UTF-8','ISO-8859-1',$child);
回显“”。“\n”;
}
}
回显“”。“\n”;
}
我看不出有什么意义,因为SimpleXMLObject可以像数组一样受到威胁
但如果你真的需要,只需在论坛或论坛中查看chassagnette的答案。这取决于CDATA、阵列等方面的一些问题。
json_decode(json_encode((array) simplexml_load_string($obj)), 1);
(见:)
我认为,这将是最好的解决方案:
public function simpleXml2ArrayWithCDATASupport($xml)
{
$array = (array)$xml;
if (count($array) === 0) {
return (string)$xml;
}
foreach ($array as $key => $value) {
if (is_object($value) && strpos(get_class($value), 'SimpleXML') > -1) {
$array[$key] = $this->simpleXml2ArrayWithCDATASupport($value);
} else if (is_array($value)) {
$array[$key] = $this->simpleXml2ArrayWithCDATASupport($value);
} else {
continue;
}
}
return $array;
}
这里是我的迭代(即使我不认为通过递归解析数据会导致堆栈爆炸)对数组的递归转换的实现。这是一种比通过json解码函数更直接的方式:
function xml2Array(SimpleXMLElement $el): stdClass {
$ret = $el;
$stack = [&$ret];
while (count($stack) > 0) {
$cur = &$stack[count($stack) - 1];
array_splice($stack, -1);
$cur = (object) (array) $cur;
foreach ($cur as $key => $child) {
$childRef = &$cur->{$key};
if ($child instanceof SimpleXMLElement)
$stack[count($stack) - 1] = &$childRef;
elseif(is_array($child))
foreach ($childRef as $ckey => $cell) {
if ($cell instanceof SimpleXMLElement)
$stack[count($stack) - 1] = &$childRef[$ckey];
}
}
}
return $ret;
}
对于那些关心CDATA案例的人 将@ajayi oluwaseun emmanuel的答案与我的工作相结合:
$xml = simplexml_load_string($xml_str, 'SimpleXMLElement', LIBXML_NOCDATA);
$json = json_encode($xml);
$arr = json_decode($json,TRUE);
除了希望将其存储在会话中的情况外,在我尝试此操作时,不允许获取“SimpleXMLElement”的序列化。因此,对阵列进行强制转换是非常必要的usefull@GromBeestje:XML已序列化。在会话中存储字符串没有问题:)每次加载脚本时解析XML字符串似乎效率低下,因此我认为存储解析后的表单是有意义的。聪明!我从来没有想过要这么做。如果可能的话,我会给你100票。这真是太棒了:)@AdamLibuša是的,但无论如何,你会如何在php数组中保存属性呢?说真的,这怎么能被接受呢?它不适用于最简单的测试用例:
empty
将转换为空数组,而不是null
。它还有一个很大的缺点,就是将所有内容都转换为字符串。但是当你有布尔或整数时,它们都被转换成字符串,这不是最优的。不确定这对其他人来说“不起作用”,但它完成了迭代所有子项和属性的工作。