2011-10-27 44 views
5

Tôi đã quay lại tất cả các mã cũ của mình và cố gắng tối ưu hóa nó. Một cái gì đó Gần đây tôi tình cờ và đã nhận tôi bối rối đang cố gắng tìm một giải pháp xpath cho việc này:Tìm phần tử cụ thể dựa trên một thuộc tính

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

nhu cầu quay trở lại $i để nó có thể được sử dụng để tham chiếu đến phần tử trong XML sau.

Có vẻ như nó sẽ là có thể, và tôi đã tìm thấy một vài xpath dây mà có vẻ như họ nên làm việc, nhưng không. Chúng thường đề cập đến preceding-children và đếm chúng thông qua hàm xpath(), nhưng tôi không thể tìm thấy các nguồn ban đầu nữa và không làm thế nào để dịch nó thành chuỗi xpath PHP.

Điều này có thể thực hiện được không? Hoặc là nó tốt hơn/nhanh hơn/hiệu quả hơn những gì tôi đã có? Gợi ý/Giải pháp?

EDIT: Đối với Tandu của Giải pháp

Ví dụ về XML của tôi tập

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

Trong chức năng PHP hiện tại, $i luôn trả 0 nhưng phải trả lại bất cứ vị trí $search được tìm thấy tại. Đã chỉnh sửa để không còn cần phải chuyển đổi simplexml nữa.

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

Trả lời

3

PHP có ít nhất hai (mà tôi biết) phương pháp để xử lý XPath: các DOMXPath thư viện, mà làm việc với DOMDocument, và SimpleXML, trong đó có phương pháp xpath() riêng của mình. Nếu bạn muốn đánh giá các biểu thức thực tế (chẳng hạn như nhận được i trong ví dụ của bạn), bạn phải sử dụng DOMXPath::evaluate(). SimpleXML::xpath() sẽ chỉ trả lại một danh sách nút (như ý DOMXPath::query(). Ngoài ra còn có xpath_ phương pháp trong php, nhưng những dường như là phiên bản chức năng của các phương pháp khác và vẫn đòi hỏi DOM đối tượng context node.

Tôi không chắc chắn những gì xml trong ví dụ của bạn ở trên là, nhưng ví dụ dưới đây sử dụng DOMXPath. đó là tôi biết, không có cách nào đơn giản để chuyển đổi SimpleXML để DOMDocument. bạn sẽ chỉ phải nạp xml riêng.

$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

Been sử dụng SimpleXML quá lâu tôi quên về dom anh trai của mình! – mseancole

+0

* Không nhận ra rằng nhập sẽ thêm nhận xét thay vì chuyển sang dòng kế tiếp XD XML của tôi, tất nhiên, simplexml. Đây là những gì tôi đã có, không chắc chắn nếu cách thanh lịch nhất, nhưng tôi vẫn không thể làm cho nó hoạt động: ( Nhập mã trong bài gốc vì tôi không thể định dạng nó ở đây đúng cách :( – mseancole

+0

@showerhead I xem xml của bạn? Lưu ý rằng "root" và "child" là các tên nút.Ví dụ: nếu bạn có '' thay vào đó, bạn sẽ thay thế "gốc" bằng "cha" và "con" bằng "con trai" trong ví dụ của tôi. Tôi thấy bạn đang sử dụng "con" trong ví dụ trong câu hỏi của bạn. –

0

sử dụng một biểu thức XPath đơn, do đó bạn không cần phải lặp lại kết quả:

elementWithSomeName[@attribute = 'someNeededValue'] 

hay (trong trường hợp "thuộc tính là một cái tên của một phần tử):

elementWithSomeName[attribute = 'someNeededValue'] 
+0

vâng, tôi đã nhận được rằng đến nay, tôi đã được lặp đi lặp lại để tôi có thể tìm thấy vị trí cụ thể của nó trong xml, do đó $ i. Cảm ơn bạn mặc dù – mseancole

Các vấn đề liên quan