XPath是一種可以對XML文檔中的某一部分進行單獨處理的一種語言,對於XSLT轉換而言它尤其重要。XPath也可作為單獨的工具管理應用程序中的XML數據,比如網絡應用程序。 微軟通過selectSingleNode() 和selectNodes()方法來提供的XPath功能,從而實現對DOM()節點和文檔的操作。然而,PHP是通過程序中的環境(context)來實現XPath功能的。我將舉例來說明如何利用PHP代碼從XML文檔中抽取不同的數據片斷,並隨後解釋這些PHP代碼是如何工作的。 在這個例子中,我使用了以下的XML數據。(注意:這些代碼是在PHP 4.3.4、Windows XP和IIS 5.1條件下開發並運行成功的。) <?xml version="1.0"?> <x:rootxmlns:x="http://www.someplace.com"> <x:row> <x:dog color="yellow">Marmaduke</x:dog> <x:cat>Garfield</x:cat> </x:row> <x:row> <x:dog color="white">Snoopy</x:dog> <x:cat>Heathcliff</x:cat> </x:row> <x:row> <x:dog color="gray">Spike</x:dog> <x:cat>Sylvester</x:cat> </x:row> </x:root> 這個XML文檔包含了一些元素(element)和屬性(attribute),還有一個名域空間(namespace)的聲明,都是一些基本的XML。在示例的PHP代碼中,我們會從這個XML文檔中得到多種的查詢結果。 <?php $sxml = '<?xml version="1.0"?> <x:rootxmlns:x="http://www.someplace.com"> <x:row> <x:dog color="yellow">Marmaduke</x:dog> <x:cat>Garfield</x:cat> </x:row> <x:row> <x:dog color="white">Snoopy</x:dog> <x:cat>Heathcliff</x:cat> </x:row> <x:row> <x:dog color="gray">Spike</x:dog> <x:cat>Sylvester</x:cat> </x:row> </x:root>'; $xml = domxml_open_mem($sxml); $xpc = XPath_new_context($xml); XPath_register_ns($xpc, "x", "http://www.someplace.com"); $nodes = XPath_eval($xpc, "//x:row/x:dog[@color='yellow']/text()"); foreach ($nodes->nodeset as $node) { print $node->content . "\n"; } $nodes = XPath_eval($xpc, "//x:row/x:dog"); foreach ($nodes->nodeset as $node) { print $xml->dump_node($node) . "\n"; } $nodes = XPath_eval($xpc, "//x:cat/child::text()//x:dog[@color='white' or @color='gray']/text()"); foreach ($nodes->nodeset as $node) { print $node->content . "\n"; } $xml->free(); ?> 首先,創建一個局部變量來存儲XML字符串,這一信息原本可以被傳遞並成為HTTP POST請求的一部分,然而,我要把它包含在代碼中;下一步是要使用domxml_open_mem()來創建一個DOM文檔,domxml_open_mem()可以從有效的XML字符串中在內存中創建一個DOM文檔對象,它只有一個參數:XML字符串;另一種方法是將XML存儲於一個單獨的文件中,然後使用domxml_open_file()從文件中讀取XML,它也只有一個參數:XML文件的文件名。 創建了DOM文檔對象之後,就可以通過XPath_new_context()來創建這一對象的XPath環境了,它只需一個參數:當前的DOM文檔對象。這一環境用於XPath表達式的運算,如果需要的話還可以用於注冊名域空間。既然在XML中已經包括了一個名域空間,則使用XPath_register_ns()來注冊名域空間,這樣才能在XPath查詢中使用前綴,XPath_register_ns()包括了三個參數:他們分別是XPath環境、前綴和名域空間。 現在可以運行XPath查詢了,可以通過XPath_eval()來實現,它的第一參數是XPath的環境,第二參數是XPath表達式,XPath_eval()將返回一個DOM節點的數組,在我的代碼中,我對節點集合進行單步調試,可以得到某些形式的輸出。 在第一個XPath例子中,我抓取了所有‘color’屬性等於‘yellow’,並且在x:row節點下的x:dog文本元素,在PHP中的XPath表達式和MSXML中的XPath有些細微的區別,我將‘/text()’部分包含在表達式中則只返回文本節點,而在MSXML中,你需要使用‘text’屬性來訪問文本節點,對返回的文本節點使用‘content’屬性則可以取得文本節點的內容。 在第二個例子中,我抓取了在x:row節點下的x:dog元素,然而,這次我對DOM文檔對象使用dump_node()方法來打印出具有適當節點的整個XML,dump_node()接受一個參數:需要轉儲內容的DOM節點。 在最後一個例子中,我抓取了所有‘color’屬性等於’gray’的所有x:cat文本節點和x:dog文本節點,我再次對節點集合進行單步調試並打印出每個節點的內容,最後釋放這個DOM文檔對象。