不从 PHP 中的 XML 返回子项


Not returning children from XML in PHP

我正在从api中检索XML,并使用PHP将其放入一个漂亮的有序数组中。

基本上,它用于类别菜单,返回 3 个级别的类别,这些类别将进入 3 层项目符号列表。

第一级的节点名称为"CustomCategory",其中有一个名为"ChildCategory"的子节点。 这是完美的,我可以在第一关中循环并回显第二关。

问题是在第二级中,第三级节点也称为"子类别"。

它看起来有点像这样:

<CustomCategories>
    <CustomCategory>
          <Name>Category 1</Name>
          <ChildCategory>
               <Name>Child 1</Name>
               <ChildCategory>
                    <Name>Child 1a</Name>
               </ChildCategory>
          <ChildCategory>
            <Name>Child 2</Name>
          </ChildCategory>
    </CustomCategory>
    <CustomCategory>
          <Name>Category 2</Name>
    </CustomCategory>
</CustomCategories>

这意味着当我循环通过第一级来获取孩子时,它不仅仅是查看第二级,而是依次通过第三级中的每个级别,因为它是相同的节点名称......

如何运行第二个循环但忽略子循环?

这是我目前的代码:

$responseDoc = new DomDocument();
$responseDoc->loadXML($responseXml);
$categories=[];
// loop level 1
foreach ($responseDoc->getElementsByTagName('CustomCategory') as $cat1) {  
          $Name1 = $cat1->getElementsByTagName('Name')->item(0)->nodeValue; 
          $cats1['name1'] = $Name1;
          // loop level 2
          foreach ($cat1->getElementsByTagName('ChildCategory') as $cat2) {
               $Name2 = $cat2->getElementsByTagName('Name')->item(0)->nodeValue;
               $cats2['name2'] = $Name2;
               $cats1['subcat']= $cats2;
          }
          $categories[] = $cats1;
} 

注意:这有点精简,因为我正在做一些时髦的事情,关于数组在进入时如何排序。

在我回应这一点的那一刻,它会创建一个列表,将所有第 2/3 级合二为一。

我想把数据放在最后,就像这样:

我需要在名称处获取的值,以便我可以将它们放入数组中并回显出来,例如:

<ul>
    <li>Category 1
        <ul>
            <li>Child1
                <ul>
                    <li>Child 1a</li>
                </ul>
            </li>
            <li>Child 2</li>
        </ul>
    </li>
    <li>Category 1</li>
</ul>

然而,第三层的孩子在第二圈出来了......

非常感谢!

DOMNode::getElementsByTagName() 返回具有该名称的所有后代元素节点。您可以循环访问 $childNodes 属性并验证每个节点类型和名称,也可以使用 Xpath。

$document = new DOMDocument();
$document->loadXml($xml);
$xpath = new DOMXpath($document);
foreach ($xpath->evaluate('/CustomCategories/CustomCategory') as $customCategory) {
  echo $xpath->evaluate('string(Name)', $customCategory), "'n";
  foreach ($xpath->evaluate('ChildCategory', $customCategory) as $childCategory) {
    echo ' -> ',  $xpath->evaluate('string(Name)', $childCategory), "'n";
  }
}

输出:

Category 1
 -> Child 1
 -> Child 2
Category 2

您提到您需要对类别进行排序。执行此操作的一种简单方法是将节点列表转换为数组并使用自定义排序。

$document = new DOMDocument();
$document->loadXml($xml);
$xpath = new DOMXpath($document);
$customCategories = iterator_to_array(
   $xpath->evaluate('/CustomCategories/CustomCategory')
);
// sort the categories by name, descending
uasort(
  $customCategories,
  function($one, $two) use ($xpath) {
    return -1 * strcasecmp(
      $xpath->evaluate('string(Name)', $one),
      $xpath->evaluate('string(Name)', $two)
    );
  }
);
foreach ($customCategories as $customCategory) {
  echo $xpath->evaluate('string(Name)', $customCategory), "'n";
  foreach ($xpath->evaluate('ChildCategory', $customCategory) as $childCategory) {
    echo ' -> ',  $xpath->evaluate('string(Name)', $childCategory), "'n";
  }
}

输出:

Category 2
Category 1
 -> Child 1
 -> Child 2