微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用PHP将嵌套的xml解析为对象

我必须用PHP将xml文件解析为一个对象.目前我不知道如何做到这一点,感谢帮助.

xml非常大.我必须解析它的一部分,如下所示:

<someNamespace:xmlDocument>
<someNamespace:categories>
    <category name="Patrick" anAttribute="numericValue" anotherAttribute="numericValue">
        <category name="Andrew" anAttribute="numericValue" anotherAttribute="numericValue">
            <category name="Alice" anAttribute="numericValue" anotherAttribute="numericValue">
                <category name="Thomas" anAttribute="numericValue" anotherAttribute="numericValue">
                    <category name="Michael" anAttribute="numericValue" anotherAttribute="numericValue"/>
                    <category name="Matthew" anAttribute="numericValue" anotherAttribute="numericValue"/>
                </category>
                <category name="Janet" anAttribute="numericValue" anotherAttribute="numericValue">
                    <category name="Steven" anAttribute="numericValue" anotherAttribute="numericValue"/>
                    <category name="Christopher" anAttribute="numericValue" anotherAttribute="numericValue"/>
                </category>
                <category name="Sue" anAttribute="numericValue" anotherAttribute="numericValue"/>
            </category>
            <category name="Charles" anAttribute="numericValue" anotherAttribute="numericValue">
                <category name="John" anAttribute="numericValue" anotherAttribute="numericValue">
                    <category name="Charles" anAttribute="numericValue" anotherAttribute="numericValue"/>
                    <category name="Rosamund" anAttribute="numericValue" anotherAttribute="numericValue"/>
                    <category name="Stuart" anAttribute="numericValue" anotherAttribute="numericValue"/>
                    <category name="Rosamund" anAttribute="numericValue" anotherAttribute="numericValue"/>
                </category>
                <category name="John" anAttribute="numericValue" anotherAttribute="numericValue"/>
            </category>
        </category>
        <category name="Oliver" anAttribute="numericValue" anotherAttribute="numericValue">
            <category name="Jane" anAttribute="numericValue" anotherAttribute="numericValue"/>
            <category name="Lucy" anAttribute="numericValue" anotherAttribute="numericValue">
                <category name="David" anAttribute="numericValue" anotherAttribute="numericValue"/>
                <category name="Robert" anAttribute="numericValue" anotherAttribute="numericValue"/>
                <category name="Hetty" anAttribute="numericValue" anotherAttribute="numericValue">
                    <category name="Kenneth" anAttribute="numericValue" anotherAttribute="numericValue"/>
                    <category name="Jonathan" anAttribute="numericValue" anotherAttribute="numericValue"/>
                </category>
                <category name="Freddy" anAttribute="numericValue" anotherAttribute="numericValue"/>
                <category name="Virginia" anAttribute="numericValue" anotherAttribute="numericValue"/>
            </category>
        </category>
    </category>
</someNamespace:categories>

每个“name”和“anAttribute”属性都是唯一的.

之后我想要的是一个带有许多类别对象的类别对象……

谢谢!

解决方法:

定义DOMDocument的扩展

class MyDOMDocument extends DOMDocument
{
    public function toArray(DOMNode $odomNode = null)
    {
        // return empty array if dom is blank
        if (is_null($odomNode) && !$this->hasChildNodes()) {
            return array();
        }
        $odomNode = (is_null($odomNode)) ? $this->documentElement : $odomNode;
        if (!$odomNode->hasChildNodes()) {
            $mResult = $odomNode->nodeValue;
        } else {
            $mResult = array();
            foreach ($odomNode->childNodes as $oChildNode) {
                // how many of these child nodes do we have?
                // this will give us a clue as to what the result structure should be
                $oChildNodeList = $odomNode->getElementsByTagName($oChildNode->nodeName);
                $iChildCount = 0;
                // there are x number of childs in this node that have the same tag name
                // however, we are only interested in the # of siblings with the same tag name
                foreach ($oChildNodeList as $oNode) {
                    if ($oNode->parentNode->isSameNode($oChildNode->parentNode)) {
                        $iChildCount++;
                    }
                }
                $mValue = $this->toArray($oChildNode);
                $sKey   = ($oChildNode->nodeName{0} == '#') ? 0 : $oChildNode->nodeName;
                $mValue = is_array($mValue) ? $mValue[$oChildNode->nodeName] : $mValue;
                // how many of thse child nodes do we have?
                if ($iChildCount > 1) {  // more than 1 child - make numeric array
                    $mResult[$sKey][] = $mValue;
                } else {
                    $mResult[$sKey] = $mValue;
                }
            }
            // if the child is <foo>bar</foo>, the result will be array(bar)
            // make the result just 'bar'
            if (count($mResult) == 1 && isset($mResult[0]) && !is_array($mResult[0])) {
                $mResult = $mResult[0];
            }
        }
        // get our attributes if we have any
        $arattributes = array();
        if ($odomNode->hasAttributes()) {
            foreach ($odomNode->attributes as $sAttrName=>$oAttrNode) {
                // retain namespace prefixes
                $arattributes["@{$oAttrNode->nodeName}"] = $oAttrNode->nodeValue;
            }
        }
        // check for namespace attribute - Namespaces will not show up in the attributes list
        if ($odomNode instanceof DOMElement && $odomNode->getAttribute('xmlns')) {
            $arattributes["@xmlns"] = $odomNode->getAttribute('xmlns');
        }
        if (count($arattributes)) {
            if (!is_array($mResult)) {
                $mResult = (trim($mResult)) ? array($mResult) : array();
            }
            $mResult = array_merge($mResult, $arattributes);
        }
        $arResult = array($odomNode->nodeName=>$mResult);
        return $arResult;
    }
}

像这样使用

$mydom = new MyDOMDocument();
$mydom->load('test.xml');

print_r($mydom->toArray());

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。