PHP:使用 simplexml 循环遍历 XML 文件的所有级别

发布于 2024-08-19 05:14:52 字数 1498 浏览 4 评论 0原文

我有一个函数,它使用 simplexml 返回 XML 文件中的第一级节点并将其写入无序列表:

function printAssetMap() {
    $xml = simplexml_load_file(X_ASSETS);
    $assets = $xml->asset;
    $html = '<ul>'."\n";
    foreach ($assets as $asset) {
        $html .= '<li id="asset'.$asset->asset_assetid.'"><ins>&nbsp;</ins><a href="#">'.$asset->asset_name.' ['.$asset->asset_assetid.']</a></li>'."\n";
    }//end foreach
    $html .= '</ul>'."\n";
    return $html;
}// printAssetMap()

我正在使用的 XML,它具有嵌套节点:

<?xml version="1.0"?>
<assets>
  <asset>
    <asset_name>Home</asset_name>
    <asset_url>/home</asset_url>
    <asset_assetid>1</asset_assetid>
  </asset>
  <asset>
    <asset_name>Projects</asset_name>
    <asset_url>/projects</asset_url>
    <asset_assetid>2</asset_assetid>
    <asset>
      <asset_name>Portfolio</asset_name>
      <asset_url>/projects/portfolio</asset_url>
      <asset_assetid>3</asset_assetid>
    </asset>
    <asset>
      <asset_name>Current Jobs</asset_name>
      <asset_url>/projects/current-jobs</asset_url>
      <asset_assetid>4</asset_assetid>
    </asset>
  </asset>
</assets>

现在,我开始添加我的节点的子节点我目前正在返回。有没有办法循环遍历 xml 文件中子节点的所有级别,即使我不知道有多少级别,并将它们添加到我的列表中?

I have a function which uses simplexml to return the first level of nodes in an XML file and write it into an unordered list:

function printAssetMap() {
    $xml = simplexml_load_file(X_ASSETS);
    $assets = $xml->asset;
    $html = '<ul>'."\n";
    foreach ($assets as $asset) {
        $html .= '<li id="asset'.$asset->asset_assetid.'"><ins> </ins><a href="#">'.$asset->asset_name.' ['.$asset->asset_assetid.']</a></li>'."\n";
    }//end foreach
    $html .= '</ul>'."\n";
    return $html;
}// printAssetMap()

XML I am using, that has nested nodes:

<?xml version="1.0"?>
<assets>
  <asset>
    <asset_name>Home</asset_name>
    <asset_url>/home</asset_url>
    <asset_assetid>1</asset_assetid>
  </asset>
  <asset>
    <asset_name>Projects</asset_name>
    <asset_url>/projects</asset_url>
    <asset_assetid>2</asset_assetid>
    <asset>
      <asset_name>Portfolio</asset_name>
      <asset_url>/projects/portfolio</asset_url>
      <asset_assetid>3</asset_assetid>
    </asset>
    <asset>
      <asset_name>Current Jobs</asset_name>
      <asset_url>/projects/current-jobs</asset_url>
      <asset_assetid>4</asset_assetid>
    </asset>
  </asset>
</assets>

Now, I am starting to add child nodes of the nodes that I am currently returning. Is there a way to loop through ALL levels of child nodes in an xml file, even if I don't know how many levels there are, and add those to my list?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

罪歌 2024-08-26 05:14:52

所以基本上你需要做的是一个函数,它获取当前节点的每个 子节点,构建 HTML,然后检查当前节点是否有 > 。 它自己的孩子,并不断在树的更深处递归。

这样做的方法如下:

function printAssetMap()
{
    return printAssets(simplexml_load_file(X_ASSETS));
}

function printAssets(SimpleXMLElement $parent)
{
    $html = "<ul>\n";
    foreach ($parent->asset as $asset)
    {
        $html .= printAsset($asset);
    }
    $html .= "</ul>\n";

    return $html;
}

function printAsset(SimpleXMLElement $asset)
{
    $html = '<li id="asset'.$asset->asset_assetid.'"><ins> </ins><a href="#">'.$asset->asset_name.' ['.$asset->asset_assetid.']</a>';

    if (isset($asset->asset))
    {
        // has <asset/> children
        $html .= printAssets($asset);
    }

    $html .= "</li>\n";

    return $html;
}

顺便说一句,我希望名为“printX”的函数实际上打印或回显某些内容,而不是返回它。也许您应该将这些函数命名为“buildX”?

So basically what you need to do is a function that takes each <asset/> child of current node, builds the HTML then checks if the current node has <asset/> children of its own and keeps recursing deeper down the tree.

Here's how you can do it:

function printAssetMap()
{
    return printAssets(simplexml_load_file(X_ASSETS));
}

function printAssets(SimpleXMLElement $parent)
{
    $html = "<ul>\n";
    foreach ($parent->asset as $asset)
    {
        $html .= printAsset($asset);
    }
    $html .= "</ul>\n";

    return $html;
}

function printAsset(SimpleXMLElement $asset)
{
    $html = '<li id="asset'.$asset->asset_assetid.'"><ins> </ins><a href="#">'.$asset->asset_name.' ['.$asset->asset_assetid.']</a>';

    if (isset($asset->asset))
    {
        // has <asset/> children
        $html .= printAssets($asset);
    }

    $html .= "</li>\n";

    return $html;
}

By the way, I would expect a function named "printX" to actually print or echo something, rather than return it. Perhaps you should name those functions "buildX" ?

夕嗳→ 2024-08-26 05:14:52

你需要使用递归函数。下面是一个从 XML 输出数组的示例。它来自 PHP 文档 - http://www.php.net/manual /en/ref.simplexml.php。您可以修改它以输出列表。

<?php 
function XMLToArray($xml) 
{ 
  if ($xml instanceof SimpleXMLElement) { 
    $children = $xml->children(); 
    $return = null; 
  } 

  foreach ($children as $element => $value) { 
    if ($value instanceof SimpleXMLElement) { 
      $values = (array)$value->children(); 

      if (count($values) > 0) { 
        $return[$element] = XMLToArray($value); 
      } else { 
        if (!isset($return[$element])) { 
          $return[$element] = (string)$value; 
        } else { 
          if (!is_array($return[$element])) { 
            $return[$element] = array($return[$element], (string)$value); 
          } else { 
            $return[$element][] = (string)$value; 
          } 
        } 
      } 
    } 
  } 

  if (is_array($return)) { 
    return $return; 
  } else { 
    return $false; 
  } 
} 
?>

you need to use a recursive function. here is an example that outputs an array from XML. It is from the PHP docs - http://www.php.net/manual/en/ref.simplexml.php. You can amend this to output a list.

<?php 
function XMLToArray($xml) 
{ 
  if ($xml instanceof SimpleXMLElement) { 
    $children = $xml->children(); 
    $return = null; 
  } 

  foreach ($children as $element => $value) { 
    if ($value instanceof SimpleXMLElement) { 
      $values = (array)$value->children(); 

      if (count($values) > 0) { 
        $return[$element] = XMLToArray($value); 
      } else { 
        if (!isset($return[$element])) { 
          $return[$element] = (string)$value; 
        } else { 
          if (!is_array($return[$element])) { 
            $return[$element] = array($return[$element], (string)$value); 
          } else { 
            $return[$element][] = (string)$value; 
          } 
        } 
      } 
    } 
  } 

  if (is_array($return)) { 
    return $return; 
  } else { 
    return $false; 
  } 
} 
?>
话少心凉 2024-08-26 05:14:52
<?php
function all_nodes($xml){
    $all=array();
    function add($node){
        array_push($all,$node);
        foreach($node as $child){
            add($child);
        }
    }
    add($xml->documentElement);
    return $all;
}
?>

这将返回一个包含文档中所有节点的数组。

<?php
function all_nodes($xml){
    $all=array();
    function add($node){
        array_push($all,$node);
        foreach($node as $child){
            add($child);
        }
    }
    add($xml->documentElement);
    return $all;
}
?>

This will return an array with all nodes in the document.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文