【问题标题】:Get Last XML Child from Tree of All Same Name Children从所有同名子级树中获取最后一个 XML 子级
【发布时间】:2017-03-21 22:17:19
【问题描述】:

我正在努力解析这个 XML 结构:

<BrowseNodes>
    <BrowseNode>
        <BrowseNodeId>6388960011</BrowseNodeId>
        <Name>Road Bike Frames</Name>
        <Ancestors>
            <BrowseNode>
                <BrowseNodeId>1266090011</BrowseNodeId>
                <Name>Bike Frames</Name>
                <Ancestors>
                    <BrowseNode>
                        <BrowseNodeId>3403201</BrowseNodeId>
                        <Name>Cycling</Name>
                        <Ancestors>
                            <BrowseNode>
                                <BrowseNodeId>706814011</BrowseNodeId>
                                <Name>Outdoor Recreation</Name>
                                <Ancestors>
                                    <BrowseNode>
                                        <BrowseNodeId>3375301</BrowseNodeId>
                                        <Name>Categories</Name>
                                        <IsCategoryRoot>1</IsCategoryRoot>
                                        <Ancestors>
                                            <BrowseNode>
                                                <BrowseNodeId>3375251</BrowseNodeId>
                                                <Name>Sports & Outdoors</Name>
                                            </BrowseNode>
                                        </Ancestors>
                                    </BrowseNode>
                                </Ancestors>
                            </BrowseNode>
                        </Ancestors>
                    </BrowseNode>
                </Ancestors>
            </BrowseNode>
        </Ancestors>
    </BrowseNode>
    <BrowseNode>
        <BrowseNodeId>11130424011</BrowseNodeId>
        <Name>Outdoor Recreation Features</Name>
        <Ancestors>
            <BrowseNode>
                <BrowseNodeId>3375251</BrowseNodeId>
                <Name>Sports & Outdoors</Name>
            </BrowseNode>
        </Ancestors>
    </BrowseNode>
</BrowseNodes>

如您所见,每个子元素都有相同的名称。我已经看到了一些使用 Xpath 等的示例……但似乎无法理解它。另外,我试过数孩子,但这显然只算第一级……所以那里没有骰子。与试图查看每个的所有子节点相同(假设 $nodes 是基于上述 xml 的 BrowseNodes)。

理想情况下,我想直接在&lt;IsCategoryRoot&gt;1&lt;/IsCategoryRoot&gt; 下获取 BrowseNode。同样,我的第一个想法是计算 的孩子,但它停留在第一级。

foreach($nodes->BrowseNode->children() as $child) {
    echo $child->getName() . "<br>";
}

感谢任何帮助。我确定我错过了一些简单的东西。

这是当项目在 simplexml 中时返回的内容(请记住,此时我已经在使用 SimpleXML 对象 - 例如,我以 $whateverItem->BrowseNodes 的形式访问它:

object(SimpleXMLElement)#6 (1) {
  ["BrowseNode"]=>
  object(SimpleXMLElement)#5 (3) {
    ["BrowseNodeId"]=>
    string(7) "3403551"
    ["Name"]=>
    string(19) "Resistance Trainers"
    ["Ancestors"]=>
    object(SimpleXMLElement)#9 (1) {
      ["BrowseNode"]=>
      object(SimpleXMLElement)#10 (3) {
        ["BrowseNodeId"]=>
        string(10) "6389526011"
        ["Name"]=>
        string(27) "Bike Trainers & Accessories"
        ["Ancestors"]=>
        object(SimpleXMLElement)#11 (1) {
          ["BrowseNode"]=>
          object(SimpleXMLElement)#12 (3) {
            ["BrowseNodeId"]=>
            string(7) "3403201"
            ["Name"]=>
            string(7) "Cycling"
            ["Ancestors"]=>
            object(SimpleXMLElement)#13 (1) {
              ["BrowseNode"]=>
              object(SimpleXMLElement)#14 (3) {
                ["BrowseNodeId"]=>
                string(9) "706814011"
                ["Name"]=>
                string(18) "Outdoor Recreation"
                ["Ancestors"]=>
                object(SimpleXMLElement)#15 (1) {
                  ["BrowseNode"]=>
                  object(SimpleXMLElement)#16 (4) {
                    ["BrowseNodeId"]=>
                    string(7) "3375301"
                    ["Name"]=>
                    string(10) "Categories"
                    ["IsCategoryRoot"]=>
                    string(1) "1"
                    ["Ancestors"]=>
                    object(SimpleXMLElement)#17 (1) {
                      ["BrowseNode"]=>
                      object(SimpleXMLElement)#18 (2) {
                        ["BrowseNodeId"]=>
                        string(7) "3375251"
                        ["Name"]=>
                        string(17) "Sports & Outdoors"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}
object(SimpleXMLElement)#5 (1) {
  ["BrowseNode"]=>
  array(2) {
    [0]=>
    object(SimpleXMLElement)#3 (3) {
      ["BrowseNodeId"]=>
      string(7) "3403551"
      ["Name"]=>
      string(19) "Resistance Trainers"
      ["Ancestors"]=>
      object(SimpleXMLElement)#11 (1) {
        ["BrowseNode"]=>
        object(SimpleXMLElement)#12 (3) {
          ["BrowseNodeId"]=>
          string(10) "6389526011"
          ["Name"]=>
          string(27) "Bike Trainers & Accessories"
          ["Ancestors"]=>
          object(SimpleXMLElement)#13 (1) {
            ["BrowseNode"]=>
            object(SimpleXMLElement)#14 (3) {
              ["BrowseNodeId"]=>
              string(7) "3403201"
              ["Name"]=>
              string(7) "Cycling"
              ["Ancestors"]=>
              object(SimpleXMLElement)#15 (1) {
                ["BrowseNode"]=>
                object(SimpleXMLElement)#16 (3) {
                  ["BrowseNodeId"]=>
                  string(9) "706814011"
                  ["Name"]=>
                  string(18) "Outdoor Recreation"
                  ["Ancestors"]=>
                  object(SimpleXMLElement)#17 (1) {
                    ["BrowseNode"]=>
                    object(SimpleXMLElement)#18 (4) {
                      ["BrowseNodeId"]=>
                      string(7) "3375301"
                      ["Name"]=>
                      string(10) "Categories"
                      ["IsCategoryRoot"]=>
                      string(1) "1"
                      ["Ancestors"]=>
                      object(SimpleXMLElement)#19 (1) {
                        ["BrowseNode"]=>
                        object(SimpleXMLElement)#20 (2) {
                          ["BrowseNodeId"]=>
                          string(7) "3375251"
                          ["Name"]=>
                          string(17) "Sports & Outdoors"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
    [1]=>
    object(SimpleXMLElement)#10 (3) {
      ["BrowseNodeId"]=>
      string(11) "11130424011"
      ["Name"]=>
      string(27) "Outdoor Recreation Features"
      ["Ancestors"]=>
      object(SimpleXMLElement)#11 (1) {
        ["BrowseNode"]=>
        object(SimpleXMLElement)#12 (2) {
          ["BrowseNodeId"]=>
          string(7) "3375251"
          ["Name"]=>
          string(17) "Sports & Outdoors"
        }
      }
    }
  }
}

【问题讨论】:

  • 尝试递归函数,如果没有返回结果,测试是否有子召回函数

标签: php xml


【解决方案1】:

Xpath 允许您从文档中获取特定节点。在 SimpleXMLSimpleXMLElement::xpath() 中允许您使用 Xpath 表达式。结果始终是 SimpleXMLElement 对象的数组(对于有效的表达式)。表达式取决于您如何定义“最后一个”。

文档中任意级别的最后一个BrowseNode元素:

$nodes = new SimpleXMLElement($xml);
var_dump($nodes->xpath('(//BrowseNode)[last()]'));

最深层次的“BrowseNode”元素(可能有多个)。基本上是没有同名后代的“BrowseNode”元素:

$nodes = new SimpleXMLElement($xml);
var_dump($nodes->xpath('//BrowseNode[not(.//BrowseNode)]'));

当然,您也可以获取所有具有值为 1 的子 IsCategoryRoot 的节点。从那里您可以获取其中的 BrowseNode:

$nodes = new SimpleXMLElement($xml);
var_dump($nodes->xpath('//BrowseNode[IsCategoryRoot=1]/Ancestors/BrowseNode'));

【讨论】:

  • 所以,此时我已经在使用一个 SimpleXML 对象(我们可以称之为 $whatever)。所以,我已经以 $whatever->BrowseNodes 的形式访问 BrowseNodes,然后我运行 $whatever->BrowseNodes->xpath('//BrowseNodes') 例如,我只得到 2 个空数组。这很令人沮丧。我已经更新了上面的问题以显示完整的 xml 响应和 SimpleXML 对象。我只是不知道为什么当我尝试使用 xpath() 时会得到这么多空数组
  • // 是文档中的任何节点,表达式开头的斜线表示它在文档的上下文中。两个后面的斜线表示所有后代(不仅是孩子)。一个点是当前节点,所以.// 是当前节点的任何后代。您需要使用它来考虑 SimpleXMLElement 引用的元素节点。但是您当前的错误可能是您访问的是BrowseNodes 而不是BrowseNode
【解决方案2】:

我认为你可以进行递归,我不确定对象的方法,但也许你可以尝试这样的事情:

$childs = $nodes->BrowseNode;

function recursiveParse($node){
   foreach($node->children() as $child) {
    echo $child->getName() . "<br>";
    $ances = $child->getAncestors();
    if($ances !== NULL)  recursiveParse($ances->BrowseNode);
  }
}

recursiveParse($childs);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-05-11
    • 1970-01-01
    • 1970-01-01
    • 2014-03-07
    • 1970-01-01
    • 1970-01-01
    • 2022-08-16
    • 1970-01-01
    相关资源
    最近更新 更多