2011-01-08 10 views
0

対応するBrowseNodeIdNameの値を得るには、ノードAncestorsをループする必要があります。 XPathを使用してこれを行うにはどうすればよいですか?私は、XPathの//Ancestors一部が実際に全体のXMLツリーを探していると思うPHP/XPath:SimpleXMLを使用してXMLで祖先ノードを反復する

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

:私は次のようなものをしようとしているが、それは働いていません。私が必要とするのは、各ノードを訪問して必要な値を取得することです。これはどうすればいいですか?下の例では、私はしたい:ヨーロッパ - >歴史 - >科目 - >本。

例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'という名前のトップ要素がないため、ノードを選択しません。間違った答えを受け入れると、他の人が誤解を招く可能性があるので、正解を受け入れることを検討してください。 –

答えて

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

+0

oic、多分単一スラッシュxpath( '/ Ancestors/BrowseNode')、次にxpath( '/ Ancestors/BrowseNode/Ancestors/BrowseNode')などを試してみてください。 – dqhendricks

+0

はおそらくxpathを必要としません。あなたは配列のような一連の子を反復処理します。 – dqhendricks

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() 

サンプルをご利用いただけます。

しかし、それは "first" Ancestors要素へのdescandantすべての検索します。最も深いところから逆さにして見ると、同じことが起こります。BrowseNode

XSLTでは、実行可能で必要な選択肢は、効率を高めるためにキーを使用することです。

+0

+1また良い答えです。 –

0

私は、正確にあなたが望むものについてあなたの説明を誤解しているかもしれませんが、うまくいけません。このスニペットは、すべての「最上位」のBrowseNode要素を探し、その上にループを作成し、関連付けられた祖先を毎回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! :-) 
}