2011-10-27 180 views
5

我一直在回顾所有旧代码并尝试优化它。这是我最近偶然发现,并且已经得到了我难倒正试图找到这一个XPath解决方案:根据属性查找特定元素

function findit($search) { 
    $i=0; 
    foreach($xml as $page) { //loop to find specific $element based on $attribute 
     if($page['src']==$search) { return $i; } 
     $i++; 
    } 
} 

需要返回$i,以便它可以在XML以后用于参考的元素。

它似乎应该是可能的,我发现了几个xpath字符串,看起来像他们应该工作,但不。他们通常引用preceding-children并通过xpath()函数对它们进行计数,但我无法再找到原始来源,也不知道如何将其转换为PHP xpath字符串。

这甚至可能吗?还是比我已经有的更好/更快/更高效?建议/解决方案?

编辑:对于我的XML的Tandu的解决方案

示例文件

<range> 
    <page src="attribute1" /> 
    <page src="attribute2" /> 
    etc... 
    <page src="attribut20" /> 
</range> 

在我目前的PHP函数,$i总是返回0但应返​​回任何位置$search在被发现。已编辑,因此不再需要转换simplexml。

function findit($search) { 
    $dom=new DOMDocument('1.0'); 
    $dom->load($file); 
    $xpath=new DOMXPath($dom); 
    $i=$xpath->evaluate("count(/range/page[@src='$search']/preceding-sibling::*)"); 
    die($dom->saveXML()); 
} 

回答

3

PHP至少有两个(据我所知),用于处理Xpath的方法:DOMXPath库,这与DOMDocument,并且SimpleXML的作品,它有自己的xpath()方法。如果您想评估实际的表达式(例如在您的示例中获取i),则必须使用DOMXPath::evaluate()SimpleXML::xpath()只会返回一个节点列表(将DOMXPath::query()。还有xpath_方法在PHP中,但这些似乎是其他方法的功能版本,但是仍然需要DOM上下文节点的对象。

我不知道是什么xml在你上面的例子是,但下面的示例使用DOMXPath,这我知道,还有就是SimpleXML转换为DOMDocument没有简单的方法。你只需要单独加载XML。

$xml = <<<XML 
    <root> 
     <child attribute="one" /> 
     <child attribute="one" /> 
     <child attribute="one" /> 
     <child attribute="one" /> 
     <child attribute="one" /> 
     <child attribute="two" /> 
     <child attribute="one" /> 
     <child attribute="one" /> 
     <child attribute="one" /> 
     <child attribute="one" /> 
     <child attribute="one" /> 
    </root> 
XML; 
$dom = new DOMDocument; 
$dom->loadXML($xml); 
//DOMXPath requires DOMDocument in its constructor 
$xpath = new DOMXPath($dom); 
//evaluate will return types .. we are expecting an int, not a DOMNodeList 
//Look for a child node of root named "child" with attribute="two" 
//Count all its preceding siblings. 
$i = $xpath->evaluate('count(/root/child[@attribute="two"]/preceding-sibling::*)'); 
+0

去过使用SimpleXML了这么久我忘了他的哥哥DOM! – mseancole

+0

*没有意识到输入会添加注释而不是移动到下一行XD 我的XML当然是simplexml。这是我得到的,不知道如果最优雅的方式,但我仍然无法得到它的工作:( 原来的帖子中添加的代码,因为我无法正确格式化在这里:( – mseancole

+0

@showerhead我可以看到你的xml?请注意,“root”和“child”是节点名称。例如,如果你有'',你可以在我的例子中将“root”替换为“father”和“child”替换为“son”。我看你在问题的例子中仍然使用“孩子”。 –

0

使用一个XPath表达式,所以你不需要迭代结果

elementWithSomeName[@attribute = 'someNeededValue'] 

或(万一“属性是一个元素的名称):

elementWithSomeName[attribute = 'someNeededValue'] 
+0

是的,我已经得到了很多,我正在迭代,以便我可以在xml中找到它的具体位置,因此$ i。谢谢你 – mseancole