2011-01-08 75 views
0

我需要循环访问Ancestors节点以获取相应的BrowseNodeIdName值。我如何使用XPath执行此操作?我想是这样的下面,但它不工作:PHP/XPath:使用SimpleXML对XML中的祖先节点进行迭代使用SimpleXML

//BrowseNode[1]//Ancestors[1]/BrowseNode/BrowseNodeId/text() 
//BrowseNode[1]//Ancestors[1]/BrowseNode/Name/text() 

我认为的XPath //Ancestors部分实际上是搜索整个XML树。我需要做的是访问每个节点以获取所需的值。我该怎么做呢?在下面的例子中,我想要:欧洲 - >历史 - >主题 - >书籍。

示例XML:

<BrowseNode> 
     <BrowseNodeId>4952</BrowseNodeId> 
     <Name>France</Name> 
     <Ancestors> 
      <BrowseNode> 
       <BrowseNodeId>4935</BrowseNodeId> 
       <Name>Europe</Name> 
       <Ancestors> 
        <BrowseNode> 
         <BrowseNodeId>9</BrowseNodeId> 
         <Name>History</Name> 
         <Ancestors> 
          <BrowseNode> 
           <BrowseNodeId>1000</BrowseNodeId> 
           <Name>Subjects</Name> 
           <IsCategoryRoot>1</IsCategoryRoot> 
           <Ancestors> 
            <BrowseNode> 
             <BrowseNodeId>283155</BrowseNodeId> 
             <Name>Books</Name> 
            </BrowseNode> 
           </Ancestors> 
          </BrowseNode> 
         </Ancestors> 
        </BrowseNode> 
       </Ancestors> 
      </BrowseNode> 
     </Ancestors> 
    </BrowseNode> 
+0

@Alejandro的答案比你接受的答案要好。接受的答案实际上是错误的,因为根本没有获得任何节点:XPath表达式`/ Ancestors/BrowseNode`没有选择任何节点,因为你的XML文档没有名为`Ancestors`的顶层元素。请考虑接受正确的答案,因为接受错误的答案可能会误导他人。 – 2011-01-08 17:10:45

回答

0
$browse_nodes = $xml->BrowseNode; 
foreach ($browse_nodes as $browse_node) { 
    echo $browse_node->BrowseNodeId.nodeValue; 
    echo $browse_node->Name.nodeValue; 
} 
+0

我不认为这有效。我拥有的XML非常庞大,并且有很多顶级`BrowseNode`元素。另外,我只对每个顶级`BrowseNode`元素的`Ancestors/BrowseNode`感兴趣。意思是,我需要这样的东西:`// BrowseNode [1]/Ancestors/BrowseNode`,然后`// BrowseNode [2]/Ancestors/BrowseNode`,然后`// BrowseNode [3]/Ancestors/BrowseNode` ..问题是//我正在搜索整棵树。我需要的是遍历每个顶级子节点`BrowseNode` – StackOverflowNewbie 2011-01-08 07:08:08

+0

oic,也许尝试单斜杠xpath('/ Ancestors/BrowseNode'),然后xpath('/祖先/浏览节点/ Ancestors/BrowseNode')等 – dqhendricks 2011-01-08 07:12:41

0

也许试图找到最后一个节点,然后提取是祖先?

<?php 

$xml = " 
    <BrowseNode> 
     <BrowseNodeId>4952</BrowseNodeId> 
     <Name>France</Name> 
     <Ancestors> 
      <BrowseNode> 
       <BrowseNodeId>4935</BrowseNodeId> 
       <Name>Europe</Name> 
       <Ancestors> 
        <BrowseNode> 
         <BrowseNodeId>9</BrowseNodeId> 
         <Name>History</Name> 
         <Ancestors> 
          <BrowseNode> 
           <BrowseNodeId>1000</BrowseNodeId> 
           <Name>Subjects</Name> 
           <IsCategoryRoot>1</IsCategoryRoot> 
           <Ancestors> 
            <BrowseNode> 
             <BrowseNodeId>283155</BrowseNodeId> 
             <Name>Books</Name> 
            </BrowseNode> 
           </Ancestors> 
          </BrowseNode> 
         </Ancestors> 
        </BrowseNode> 
       </Ancestors> 
      </BrowseNode> 
     </Ancestors> 
    </BrowseNode> 
"; 


$sxe = simplexml_load_string($xml); 

// Set the target to reach 
$target = current($sxe->xpath("//BrowseNode[./BrowseNodeId = '283155']")); 

// Get all names from root to target 
$names = array_map('strval', $target->xpath('ancestor-or-self::Ancestors/BrowseNode/Name')); 
print_r($names); 
// Array 
// (
//  [0] => Europe 
//  [1] => History 
//  [2] => Subjects 
//  [3] => Books 
//) 

// Get all ids from root to target 
$ids = array_map('strval', $target->xpath('ancestor-or-self::Ancestors/BrowseNode/BrowseNodeId')); 
print_r($ids); 
// Array 
// (
//  [0] => 4935 
//  [1] => 9 
//  [2] => 1000 
//  [3] => 283155 
//) 

// Final 
$combined = array_combine($ids, $names); 
print_r($combined); 
// Array 
// (
//  [4935] => Europe 
//  [9] => History 
//  [1000] => Subjects 
//  [283155] => Books 
//) 
1

在下面的例子中,我想:欧洲 - >历史 - >科目 - >书籍。

我想你需要:

//Ancestors/BrowseNode/Name 

或者只是遍历//Ancestors/BrowseNode结果与任何DOM方法得到NameBrowseNodeId孩子。

0
/BrowseNode/Ancestors//BrowseNode/Name/text() 

将与您合作样本。

但是,它会搜索所有节点descandant到“第一个”Ancestors元素。从最深的BrowseNode逆转和寻找将几乎相同。

在XSLT中,可行和必要的替代方法是使用密钥来提高效率。

0

我可能误解了你对你想要的描述,但希望不会。这段代码会查找所有“顶级”元素并循环遍历它们,每次获取其关联的祖先BrowseNode元素。

// Get top level BrowseNode elements 
$browse_nodes = $xml->xpath('//BrowseNodes/BrowseNode'); 
foreach ($browse_nodes as $browse_node) { 
    // Get ancestor BrowseNode elements 
    $ancestors = $browse_node->xpath('Ancestors//BrowseNode'); 
    // Do whatever you like with them! :-) 
}