我正在学习PHP SimpleXML,我有一些问题。 我一直在玩我的工作内联网中的网络代码。我可以随时使用通用代码,因为代码可能随时发生变化。 在我的例子中,我选择了一个div标签及其所有子节点。
... <div class="cabTabs"> <ul> <li><a href="/link1">Info1</a></li> <li><a href="/link2">Info2</a></li> <li><a href="/link3">Info3</a></li> </ul> </div> ... //Get all web content: $b = new sfWebBrowser(); //using symfony 1.4.17 sfWebBrower to get a SimpleXML object. $b->get('http://intranetwebexample'); //returns a sfWebBrower object. $xml = $b->getResponseXML(); //returns a SimpleXMLElement //[Eclipse xdebug Watch - $xml] "$xml" SimpleXMLElement @attributes Array [3] head SimpleXMLElement body SimpleXMLElement //Get the div class="cabTabs". $result = $xml->xpath('//descendant::div[@class="cabTabs"]'); //[Eclipse xdebug Watch - $result] "$result" Array [1] 0 SimpleXMLElement @attributes Array [1] class cabTabs ul SimpleXMLElement li Array [6]
问题:
2.1有时我无法将SimpleXML树扩展为多个或多个级别。在上面的示例中,我无法访问/查看下面的“li”节点,并查看其子节点
它可能是使用SimpleXML对象的xdebug调试器的限制,还是Eclipse Watch的限制?
当我使用通常的循环访问其父级时,我可以完美地展开/查看“li”节点:foreach($ ul-&gt; li as $ li)。
然而,它不是一个关键的错误,我认为直接看到它并在适当的论坛上报告是完美的。
2.2我不理解$ xml-&gt; xpath的所有结果代码:
如果我们看看Eclipse Watch,“div”标签已被转换为0索引键,但“ul”和“li”标签有原始名称,为什么?
2.3如何使用通用代码访问/循环xpath内容:
我使用以下非通用代码来访问它:
foreach ($result as $record) { foreach($record->ul as $ul) { foreach($ul->li as $li) { foreach($li->a as $a) { echo ' ' . $a->name; } } } }
上述代码有效,但前提是我们编写正确的标记名称。 ( - &gt; ul, - &gt; li, - &gt; a ..)
循环遍历其所有内容而不必每次都指定子名称的通用方法是什么? ( - &gt; ul, - &gt; li, - &gt; a ..)
此外,我宁愿不必将其转换为数组,除非它是正确的方式
我一直在尝试使用children()属性,但它不起作用,它会在该行停止并崩溃:foreach($ result-&gt; children()为$ ul)
非常感谢你花时间阅读我的问题。任何帮助真的很受欢迎:)
系统信息:
symfony 1.4.17 with sfWebBrowserPlugin,cURL dadapter。
启用了cURL支持的PHP 5.4.0,cURL信息7.24.0
答案 0 :(得分:1)
我不知道自己从未使用过它
不知道我通常使用Zend Debug - 但我还是不明白你的问题......我想你遗漏了一些话: - )
2.1可能xdebug / eclipse。 Id检查首选项可能是一个限制递归量以帮助管理内存的设置。
2.2 SimpleXML::xpath
始终返回匹配节点的数组。这就是为什么你有结果的整数索引数组。因此,如果您执行//someelement
,则会获得所有someelement
个标记的数组。然后,您可以像$someelement->itschildelement
一样以正常方式访问其后代。
2.3 $result->children()
是获得一般意义上的事物的好方法。如果Xdebug崩溃只是xdebug。要么关闭它,忽略它,要么找到一个不同的调试器:-) Xdebug是一个工具,但不应该决定你如何实现。
答案 1 :(得分:0)
我认为现在我完全理解问题2.2和2.3。
由于它的xpath返回一个Array [1],如你所解释的,而不是SimpleXML对象,我不能使用$ result-&gt; children()因为php数组没有child()属性。 (我有点白痴哈哈)。
解决方案很简单,正如您所解释的那样,计算数组的元素数量,循环到元素中,然后使用children属性再次循环,如果它是SimpleXML对象。我会在下面添加正确的代码。
我还会将Eclipse Watch或xdebug的第1点问题提交到他们的论坛,以便猜测真正的问题。
谢谢prodigitalson,非常有用的答案:)
答案 2 :(得分:0)
像魅力嘿嘿一样工作。
这里我添加一个完整的函数,它以递归的方式在节点的所有属性中搜索子字符串,并返回找到它的完整字符串。
在我的情况下,它非常适合搜索某些值,例如href =和其他dinamically生成的标记值。
还显示了我们上面谈到的内容的实现。可能它可以改进,可以添加更安全的检查。
/* public function bSimpleXMLfindfullstringwithsubstring($node, $sSearchforsubstring, &$sFullstringfound, &$bfoundsubstring) * Recursive function to search for the first substring in a list of SimpleXML objects, looking in all its children, in all their attributes. * Returns true if the substring has been found. * Parameter return: * $sFullstringfound: returns the full string where the substring has been found. * $bfoundsubstring: returns true if the substring has been found. */ public function bSimpleXMLfindfullstringwithsubstring($node, $sSearchforsubstring, &$sFullstringfound, &$bfoundsubstring=false) { $bRet = false; if ((isset($node) && ($bfoundsubstring == false))) { //If the node has attributes if ($node->attributes()->count() > 0) { //Search the string in all the elements of the current SimpleXML object. foreach ($node->attributes() AS $name => $attribute) //[$name = class , (string)$attribute = cabTabs, $attribute = SimpleXML object] { //(Take care of charset if necessary). if (stripos((string)$attribute, $sSearchforsubstring) !== false) { //substring found in one of the attributes. $sFullstringfound = (string)$attribute; $bfoundsubstring = true; $bRet = true; break; } } } //If the node has childrens (subnodes) if (($node->count() > 0) && ($bfoundsubstring == false)) { foreach ($node->children() as $nodechildren) { if ($bfoundsubstring == false) { //Search in the next children. self::bSimpleXMLfindfullstringwithsubstring($nodechildren, $sSearchforsubstring, $sFullstringfound, $bfoundsubstring); } else { break; } } } } return $bRet; }
如何称呼它:
$b = new sfWebBrowser(); $b->get('http://www.example.com/example.html'); $xml = $b->getResponseXMLfixed(); $result = $xml->xpath('//descendant::div[@class="cabTabs"]'); //example $sFullString = ""; $bfoundsubstring = false; foreach ($result as $record) { self::bSimpleXMLfindfullstringwithsubstring($record, "/substring/tosearch", $sFullString, $bfoundsubstring); }