Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/228.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP XML-如何构建与父子关系处于同一级别的XML节点树_Php_Xml Parsing - Fatal编程技术网

PHP XML-如何构建与父子关系处于同一级别的XML节点树

PHP XML-如何构建与父子关系处于同一级别的XML节点树,php,xml-parsing,Php,Xml Parsing,我试图从一个文件中读取xml并像树一样显示它们。我正在使用PHP,希望得到如下所示的输出。xml文件的内容如下所示。。。 1. 父1 1. 父1 2. 儿童1 1. 父1 3. 儿童2 1. 父1 8. 孙儿1-1 2. 儿童1 12 家长2 12 家长2 15 儿童2-1 12 家长2 我想读这个xml文件(我知道怎么读),但我不能像下面那样格式化它。。。如何获取最顶层父节点的所有节点,并获取这些父节点的子节点(使用递归或其他方法) 父1 儿童1 孙儿1-1 儿童2 家长2

我试图从一个文件中读取xml并像树一样显示它们。我正在使用PHP,希望得到如下所示的输出。xml文件的内容如下所示。。。


1.
父1
1.
父1
2.
儿童1
1.
父1
3.
儿童2
1.
父1
8.
孙儿1-1
2.
儿童1
12
家长2
12
家长2
15
儿童2-1
12
家长2
我想读这个xml文件(我知道怎么读),但我不能像下面那样格式化它。。。如何获取最顶层父节点的所有节点,并获取这些父节点的子节点(使用递归或其他方法)

  • 父1
    • 儿童1
      • 孙儿1-1
    • 儿童2
  • 家长2
    • 儿童2-1
如果您有任何帮助,我们将不胜感激

编辑*我到目前为止所做的事情

$xml= simplexml_load_string('myxmlstring');

get_categories($xml, 0);

function get_categories($xml, $id) {

    if ($id==0) 
        $Categories = $xml->xpath('Categories/Category[ParentId=Id]');
    else
        $Categories = $xml->xpath('Categories/Category[ParentId='.$id.' and Id!='.$id.']');

    echo '<ul id="catlist'.$id.'">';
    foreach($Categories as $Category) {
        echo "<li>ID: " . $Category->Id . "--Name: " . $Category->Name;
        get_categories($xml, $Category->Id);
        echo "</li>";

    }
    echo "</ul>";
}
$xml=simplexml\u load\u string('myxmlstring');
获取类别($xml,0);
函数get_categories($xml,$id){
如果($id==0)
$Categories=$xml->xpath('Categories/Category[ParentId=Id]');
其他的
$Categories=$xml->xpath('Categories/Categories[ParentId='.$id.'和id!='.$id.]');
echo'
    ”; foreach($Categories作为$Category){ echo“
  • ID:.$Category->ID”-Name:.$Category->Name; 获取类别($xml,$Category->Id); 回声“
  • ”; } 回声“
”; }

现在我只想确认这是最佳解决方案。或者有人能想出更好的主意……

ParentName太过分了,只需输入parentid就足够了

因为您对每个节点进行搜索,所以执行时间将是O(N2),其中N是节点总数

不过,在线性时间中可以选择这样做:首先遍历数据并构建树结构(或某种程度上),然后遍历该结构并根据它输出节点

在这里也是一个不错的选择

// init
$childrenReferences = array();
$rootNodes = array();
$xmlNodes = array();

// gathering structure
$cats = $xml->getElementsByTagName('Category');
for ($i = 0; $i < $cats->length; $i++) {
    $cat = $cats[$i];
    $id = $children->Id;
    $parentId = $cat->ParentId;
    $xmlNodes[$id] = $cat;
    if ($parentId == $id) {
        $rootNodes []= $id;
        continue;
    }
    if (array_key_exists($parentId, $childrenReferences)) {
        $childrenReferences[$parentId] []= $id;
    } else {
        $childrenReferences[$parentId] = array($id);
    }

}

// output
function out_nodes($nodes) {
    global $childrenReferences, $xmlNodes; // this is not required since php 5.3 or something about
    echo "<ul>";
    foreach ($nodes as $id) {
        $cat = $xmlNodes[$id];
        echo "<li>ID: " . $cat->Id . "--Name: " . $cat->Name;
        if (array_key_exists($id, $childrenReferences)) { // intermediate node
            out_nodes($childrenReferences[$id]);
        }
        echo "</li>";
    }
    echo "</ul>";
}

ob_start();
out_nodes($rootNodes);
ob_end_flush();
//初始化
$childrenReferences=array();
$rootNodes=array();
$xmlNodes=array();
//聚集结构
$cats=$xml->getElementsByTagName('Category');
对于($i=0;$i<$cats->length;$i++){
$cat=$cats[$i];
$id=$children->id;
$parentId=$cat->parentId;
$xmlNodes[$id]=$cat;
如果($parentId==$id){
$rootNodes[]=$id;
继续;
}
如果(数组\键\存在($parentId,$childrenReferences)){
$childrenReferences[$parentId][]=$id;
}否则{
$childrenReferences[$parentId]=数组($id);
}
}
//输出
函数输出节点($nodes){
全局$childrenReferences,$xmlNodes;//这不是必需的,因为PHP5.3或关于
回声“
    ”; foreach($id为节点){ $cat=$xmlNodes[$id]; echo“
  • ID:.$cat->ID。”--Name:.$cat->Name; 如果(数组\键\存在($id,$childrenReferences)){//中间节点 out_节点($childrenReferences[$id]); } 回声“
  • ”; } 回声“
”; } ob_start(); out_节点($rootNodes); ob_end_flush();

代码可能无法工作,甚至无法编译,但您可以理解。

谢谢kirilloid。。。。这是很大的帮助。。。我正在使用一些修改的代码。。。xml来自curl,我知道ParentName是多余的,但我无法控制它。这是最后的代码

$childrenReferences = array();
$rootNodesIDs = array();
$xmlNodes = array();

$dom = new DOMDocument;
$dom->loadXML($xml);

$Categories = $dom->getElementsByTagName('Category');
$length = $Categories->length;

for ($i = 0; $i < $length; $i++) {
    $cat = $Categories->item($i);           //Get the DOMNode 
    $id = $cat->getElementsByTagName('Id')->item(0)->nodeValue;
    $parentId = $cat->getElementsByTagName('ParentId')->item(0)->nodeValue;
    $xmlNodes[$id] = $cat;      

    if ($parentId == $id) {
        $rootNodesIDs []= $id;
        continue;
    }

    if (array_key_exists($parentId, $childrenReferences)) {
        $childrenReferences[$parentId] []= $id;         
    } else {
        $childrenReferences[$parentId] = array($id);
    }
}

function out_nodes($rootids) {
    global $childrenReferences, $xmlNodes;

    echo "<ul>";
    foreach ($rootids as $id) {
        $cat = $xmlNodes[$id];
        echo "<li>ID: " . $cat->getElementsByTagName('Id')->item(0)->nodeValue . "--Name: " . $cat->getElementsByTagName('Name')->item(0)->nodeValue;
        if (array_key_exists($id, $childrenReferences)) { // intermediate node
            out_nodes($childrenReferences[$id]);
        }
        echo "</li>";
    }
    echo "</ul>";
}

ob_start();
out_nodes($rootNodesIDs);
ob_end_flush();
$childrenReferences=array();
$rootNodesIDs=array();
$xmlNodes=array();
$dom=新的DOMDocument;
$dom->loadXML($xml);
$Categories=$dom->getElementsByTagName('Categories');
$length=$Categories->length;
对于($i=0;$i<$length;$i++){
$cat=$Categories->item($i);//获取DOMNode
$id=$cat->getElementsByTagName('id')->item(0)->nodeValue;
$parentId=$cat->getElementsByTagName('parentId')->item(0)->nodeValue;
$xmlNodes[$id]=$cat;
如果($parentId==$id){
$rootNodesIDs[]=$id;
继续;
}
如果(数组\键\存在($parentId,$childrenReferences)){
$childrenReferences[$parentId][]=$id;
}否则{
$childrenReferences[$parentId]=数组($id);
}
}
函数输出\u节点($rootids){
全局$childrenReferences,$xmlNodes;
回声“
    ”; foreach($rootids作为$id){ $cat=$xmlNodes[$id]; echo“
  • ID:.$cat->getElementsByTagName('ID')->项(0)->节点值。”--Name:.$cat->getElementsByTagName('Name')->项(0)->节点值; 如果(数组\键\存在($id,$childrenReferences)){//中间节点 out_节点($childrenReferences[$id]); } 回声“
  • ”; } 回声“
”; } ob_start(); out_节点($rootNodesIDs); ob_end_flush();
// init
$childrenReferences = array();
$rootNodes = array();
$xmlNodes = array();

// gathering structure
$cats = $xml->getElementsByTagName('Category');
for ($i = 0; $i < $cats->length; $i++) {
    $cat = $cats[$i];
    $id = $children->Id;
    $parentId = $cat->ParentId;
    $xmlNodes[$id] = $cat;
    if ($parentId == $id) {
        $rootNodes []= $id;
        continue;
    }
    if (array_key_exists($parentId, $childrenReferences)) {
        $childrenReferences[$parentId] []= $id;
    } else {
        $childrenReferences[$parentId] = array($id);
    }

}

// output
function out_nodes($nodes) {
    global $childrenReferences, $xmlNodes; // this is not required since php 5.3 or something about
    echo "<ul>";
    foreach ($nodes as $id) {
        $cat = $xmlNodes[$id];
        echo "<li>ID: " . $cat->Id . "--Name: " . $cat->Name;
        if (array_key_exists($id, $childrenReferences)) { // intermediate node
            out_nodes($childrenReferences[$id]);
        }
        echo "</li>";
    }
    echo "</ul>";
}

ob_start();
out_nodes($rootNodes);
ob_end_flush();
$childrenReferences = array();
$rootNodesIDs = array();
$xmlNodes = array();

$dom = new DOMDocument;
$dom->loadXML($xml);

$Categories = $dom->getElementsByTagName('Category');
$length = $Categories->length;

for ($i = 0; $i < $length; $i++) {
    $cat = $Categories->item($i);           //Get the DOMNode 
    $id = $cat->getElementsByTagName('Id')->item(0)->nodeValue;
    $parentId = $cat->getElementsByTagName('ParentId')->item(0)->nodeValue;
    $xmlNodes[$id] = $cat;      

    if ($parentId == $id) {
        $rootNodesIDs []= $id;
        continue;
    }

    if (array_key_exists($parentId, $childrenReferences)) {
        $childrenReferences[$parentId] []= $id;         
    } else {
        $childrenReferences[$parentId] = array($id);
    }
}

function out_nodes($rootids) {
    global $childrenReferences, $xmlNodes;

    echo "<ul>";
    foreach ($rootids as $id) {
        $cat = $xmlNodes[$id];
        echo "<li>ID: " . $cat->getElementsByTagName('Id')->item(0)->nodeValue . "--Name: " . $cat->getElementsByTagName('Name')->item(0)->nodeValue;
        if (array_key_exists($id, $childrenReferences)) { // intermediate node
            out_nodes($childrenReferences[$id]);
        }
        echo "</li>";
    }
    echo "</ul>";
}

ob_start();
out_nodes($rootNodesIDs);
ob_end_flush();