2011-01-08 112 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! :-) 
}