【问题标题】:Build an array as a tree structure from an XML file从 XML 文件将数组构建为树结构
【发布时间】:2016-08-03 09:36:58
【问题描述】:

我正在尝试读取此 xml 文件,但我尝试制作的代码应该适用于任何 xml 文件:

<?xml version="1.0"?>
<auto>
    <binnenkant>
        <voorkant>
            <stuur/>
            <gas/>
        </voorkant>
        <achterkant>
            <stoel/>
            <bagage/>
        </achterkant>
    </binnenkant>
    <buitenkant>
        <dak>
            <dakkoffer>
                <sky/>
                <schoen/>
            </dakkoffer>    
        </dak>
        <trekhaak/>
        <wiel/>
    </buitenkant>
</auto>

我正在使用以下两个函数将 XML 文件转换为数组并将该数组转换为树。
我试图保持 XML 文件的父子关系。我从第二个函数中得到的只是一个包含 xml 文件中所有标签的数组。

有人可以帮帮我吗?

function build_xml_tree(array $vals, $parent, $level) {
    $branch = array();

    foreach ($vals as $item) {
        if (($item['type'] == "open") || $item['type'] == "complete") {
            if ($branch && level == $item['level']) {
                array_push($branch, ucfirst(strtolower($item['tag'])));
            } else if ($parent == "" || $level < $item['level']) {
                $branch = array(ucfirst(strtolower($item['tag'])) => build_xml_tree($vals, strtolower($item['tag']), $level));
            }
        }
    }
    return $branch;
}

function build_tree ($begin_tree, $content_naam) {
    $xml = file_get_contents('xml_files/' . $content_naam . '.xml');
    $p = xml_parser_create();
    xml_parse_into_struct($p, $xml, $vals, $index);

    ?>
    <pre>
    <?php
    print_r($vals);
    ?>
    </pre>
    <?php

    $eindarray = array_merge($begin_tree, build_xml_tree($vals, "", 1));

    return $eindarray;
}

【问题讨论】:

  • 你听说过DOMDocument吗?
  • 有没有可以在 DOMDocument 中使用的函数?
  • 一个DOMDocument 对象已经代表一棵树
  • 过去几个小时我一直在研究 DOMDocument,但我仍然没有找到将我的 xml TAGS 放入树中的方法。将值放入树中非常容易,是的。但我需要的是标签。
  • 只是为了澄清:您的要求是有一个像树一样结构的数组,其键由节点标签名称组成?

标签: php xml


【解决方案1】:

有许多类可以加载 XML 文件。其中许多已经以树状结构表示文件:DOMDocument 就是其中之一。

当您已经在 DOMDocument 对象中拥有一棵树时,您想将一棵树作为数组创建似乎有点奇怪:因为您必须以某种方式遍历数组树......为什么不你不是直接遍历对象树的树结构进行打印吗?

无论如何,以下代码应该可以满足您的要求:我使用了一个递归函数,其中数组树通过引用传递。 此时安排我的代码以更好地满足您的需求应该是微不足道的 - 即用更多 case 块完成 switch 语句。

  • $tree 数组的每个节点级别都有一个数字键
  • 标签节点名称是字符串值
  • 如果数组后跟一个字符串值,则它包含节点的子节点
  • 任何潜在的文本节点都作为子节点受到威胁

function buildTree(DOMNode $node = NULL, &$tree) {

    foreach ($node->childNodes as $cnode) {

        switch($cnode->nodeType) {
            case XML_ELEMENT_NODE:
                $tree[] = $cnode->nodeName;
                break;
            case XML_TEXT_NODE:
                $tree[] = $cnode->nodeValue;
                break;
        }

        if ($cnode->hasChildNodes())
            buildTree($cnode, $tree[count($tree)]);
    }
}

$source ='the string which contains the XML';

$doc = new DOMDocument();
$doc->preserveWhiteSpace = FALSE;
$doc->loadXML($source, LIBXML_NOWARNING);

$tree = array();
buildTree($doc, $tree);

var_dump($tree);

【讨论】:

  • 是的,这解决了当您有 2 个或多个连续的同名节点时第二个键会覆盖以前的值时的问题:如果一个数组跟随一个字符串值,它包含节点的子节点“字符串值”是父节点的标签
  • 这几乎解决了我的问题,唯一缺少的是父母需要是一个数组,而不是一个字符串。这些父母的孩子需要放入该数组中。
  • 我认为如果上述内容不符合您的需求,您最好在问题中提供 XML 输入和预期的数组输出
  • 标签作为数组键是我的第一种方法,但由于同一级别的相同标签覆盖了前一个键
  • 它确实符合我的需求,我只需要更改一些我在 php 中显示 bij 树的方式,然后它看起来就像我想要的那样。再次感谢您的帮助。
猜你喜欢
  • 2010-11-11
  • 1970-01-01
  • 2021-12-25
  • 2014-10-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-04
  • 2021-12-31
相关资源
最近更新 更多