2012-02-08 59 views
1

我正在使用亚马逊产品广告API的接口。xpath从嵌套元素中获取数据

我有XML,其中包括类似如下的内容:

<BrowseNodes> 
    <BrowseNode> 
    <Name>Category</Name> 
    <BrowseNodeId>123456</BrowseNodeId> 
    <Ancestors> 
     <BrowseNode> 
     <Name>Whatever</Name> 
     <BrowseNodeId>987654</BrowseNodeId> 
     <BrosweNode> 
    </Ancestors> 
    </BroseNode> 
    <BroseNode> 
    ... 
    </BrowseNode> 
</BrowseNodes> 

我得仔细检查我的XML。除了我上面发布的第一个<BrowseNode>以外,可能还有一个级别为<BrowseNode></BrowseNode>

我需要找到<BrowseNode><Name>那是祖先元素中,其中<Ancestors>元素是<Name>类别</Name>

我刚开始使用的XPath的兄弟,这是在我的头上。

我一直在编码这样的:

//$XML fromapi 
$parsed=simplexml_load_string($XML); 

//narrow it down 
$s = '/ItemSearchResponse/Items/Item'; 
$items = $parsed->xpath($s); 

//Get only the top level BrowseNodes for this item. 
foreach($items as $item) 
    { 
    // this narrows it down close to what I posted above. 
    $s = 'BrowseNodes/BrowseNode'; 
    $top_browsenode_search=$item->xpath($s); 

     //there may be a simpler way, but I think it is working for me: 
     foreach ($top_browsenode_search as $top_browsenode) 
     { 
      $temp_array=array();//must be emptied each time. 
      $s = 'Name'; 
      $temp_array['name']=$top_browsenode->xpath($s); 
      $s = 'BrowseNodeId'; 
      $temp_array['id']=$top_browsenode->xpath($s); 

     $browsenodes[]=$temp_array; 
     } 
    $top_browsenodes[]=$browsenodes; 
    unset ($browsenodes);   
    }  

有没有人能够帮助与XPath语法?如果不是直接的话,你能否指点我所知道的任何新手友好的文档?我就这个主题下载了一本很棒的书,我从中学到了很多东西,但是它有点凌驾于我的头上。

以下不是问题的一部分,而是证明其中一个答案是正确的。详情请参阅评论。 预期的结果: “随便” 给定结果: “无论”

<?xml version="1.0" ?> 
<root> 
<BrowseNodes> 
    <BrowseNode> 
    <Name>Category</Name> 
    <BrowseNodeId>123456</BrowseNodeId> 
    <Ancestors> 
     <BrowseNode> 
     <Name>Whatever</Name> 
     <BrowseNodeId>987654</BrowseNodeId> 
     </BrowseNode> 
    </Ancestors> 
    </BrowseNode> 
    <BrowseNode> 
    <Name>SomethingElse</Name> 
    <BrowseNodeId>951753</BrowseNodeId> 
    </BrowseNode> 
</BrowseNodes> 
</root> 
BrowseNodes/BrowseNode/Name 
Array 
(
    [0] => SimpleXMLElement Object 
     (
      [0] => Category 
     ) 

    [1] => SimpleXMLElement Object 
     (
      [0] => SomethingElse 
     ) 

) 

BrowseNodes/BrowseNode[Name="Category"]/Ancestors/BrowseNode/Name 
Array 
(
    [0] => SimpleXMLElement Object 
     (
      [0] => Whatever 
     ) 

) 

谢谢!

回答

1

如果你想要得到的只是节点:

BrowserNodes/BrowserNode[Name=_______]/Ancestors/BrowserNode/Name 

如果你想获得该节点的文本:

BrowserNodes/BrowserNode[Name=_______]/Ancestors/BrowserNode/Name/text() 

在这两个例子中,使用的名称替换_你正在搜索。

+0

谢谢,它看起来像我需要你的第二个,我会做$ S =“BrowseNodes/BrowseNode [名称=类别] /祖先/ BrowserNode /名称/文本( )'但是这是否遍历了深度,还是我需要知道它的嵌套深度? – TecBrat 2012-02-08 04:20:18

+0

如果你不确定'BrowserNodes'(带有“s”)是多么深的嵌套,在整个事物的前面添加'descendant ::'。顺便说一下,我对XPath的这个级别知之甚少。我只是使用[this](http://www.w3schools.com/xpath/xpath_axes.asp)。 – Zenexer 2012-02-08 04:26:33

+0

我发现(至少对我而言)总是有学习曲线,即使在理解新技术的文档时也是如此。我仍在研究这个问题,所以我很欣赏你能够将这些信息分解到我目前的水平。我将采取这种做法,不仅要获得这一块数据,还要进一步理解xpath查询。谢谢! – TecBrat 2012-02-08 13:39:36

-1

查找下面的例子:

<?php 
$xmlString =" 
<BrowseNodes> 
    <BrowseNode> 
    <Name>Category</Name> 
    <BrowseNodeId>123456</BrowseNodeId> 
    <Ancestors> 
     <BrowseNode> 
     <Name>Whatever</Name> 
     <BrowseNodeId>987654</BrowseNodeId> 
     </BrowseNode> 
    </Ancestors> 
    </BrowseNode> 
<BrowseNode> 
    <Name>Category</Name> 
    <BrowseNodeId>123456</BrowseNodeId> 
    <Ancestors> 
     <BrowseNode> 
     <Name>Whatever</Name> 
     <BrowseNodeId>987654</BrowseNodeId> 
     </BrowseNode> 
    </Ancestors> 
    </BrowseNode> 
</BrowseNodes>"; 
$result= simplexml_load_string($xmlString); 
$counter =0; 
$newArray=array(); 
foreach($result->BrowseNode as $arr) { 
    $newArray[$counter]['Name'] =(string)$arr->Name; 
    $newArray[$counter]['BrowseNodeId'] =(string)$arr->BrowseNodeId; 
    $newArray[$counter]['Ancestors']['Name'] =(string)$arr->Ancestors->BrowseNode->Name; 
    $newArray[$counter]['Ancestors']['BrowseNodeId'] =(string)$arr->Ancestors->BrowseNode->BrowseNodeId;  
    $counter++; 
} 
print"<pre>"; 
print_r($newArray); 
die; 
?> 
+0

这并不是真正的原始海报所要求的。我相信TecBrat已经能够使用这种技术。现在他想用XPath简化它。 – Zenexer 2012-02-09 04:04:09

+0

我实际上重新提出了我的问题并再次发布。我被给了这段代码,它工作:'BrowseNodes/BrowseNode // BrowseNode [Name =“Categories”]'看起来我真正需要的是双斜线。我现在已经可以用这些新知识做一些类似的搜索。 **他** :) – TecBrat 2012-02-09 04:39:31

+0

噢,我遗漏了部分工作代码:'BrowseNodes/BrowseNode // BrowseNode [Name =“Categories”]/Ancestors/BrowseNode/Name/text()' – TecBrat 2012-02-09 04:52:24