从所有同名儿童的树中获取最后一个XML子项

时间:2016-11-08 10:18:33

标签: php xml

我正在努力解析这个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等的例子......但似乎无法绕过它。另外,我已经尝试过对孩子们进行计数了,但这显然只算第一级...所以没有骰子。同样只是试图查看每个子节点(假设$节点是基于上面的xml的BrowseNodes)。

理想情况下,我想直接在<IsCategoryRoot>1</IsCategoryRoot>下阻止BrowseNode。再一次,我的第一个想法是计算孩子的数量,但它坚持第一级。

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

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

这是项目在simplexml中时返回的内容(请记住,此时我已经使用了SimpleXML对象 - 例如我将其作为$ whateverItem-&gt; 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"
        }
      }
    }
  }
}

2 个答案:

答案 0 :(得分:2)

Xpath允许您从文档中获取特定节点。在SimpleXML中SimpleXMLElement::xpath()允许您使用Xpath表达式。结果始终是SimpleXMLElement对象的数组(对于有效的表达式)。表达式取决于您如何定义&#39; last&#39;。

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

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

&#34; BrowseNode&#34;最深层次的元素(多种可能)。基本上是&#34; BrowseNode&#34;没有该名称后代的元素:

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

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

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

答案 1 :(得分:0)

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

$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);