日韩久久久精品,亚洲精品久久久久久久久久久,亚洲欧美一区二区三区国产精品 ,一区二区福利

QueryPath, php上的jQuery

系統(tǒng) 3397 0

?

?

紅得發(fā)紫的jQuery框架是專門用于頁(yè)面Javascript程序設(shè)計(jì)的,它通過(guò)一種優(yōu)雅的方式讓我們輕松自如地操作頁(yè)面的所有元素而無(wú)須擔(dān)心瀏 覽器版本以及兼容性等問(wèn)題。受到j(luò)Query的啟發(fā),一種試圖讓W(xué)eb開(kāi)發(fā)者在PHP中直接采用jQuery方式操縱和生成HTML/XML元素的 QueryPath計(jì)劃開(kāi)始了,庫(kù)的發(fā)開(kāi)者是 Matt Butcher

?

QueryPath可以很方便地讀入和生成HTML/XML,使用jQuery類似的語(yǔ)法和函數(shù)遍歷文檔對(duì)象,支持遠(yuǎn)程URL文件的讀取和分析。支 持標(biāo)準(zhǔn)的CSS3 Selector和XPath,這意味著我們可以使PHP像jQuery一樣,隨心所欲地玩轉(zhuǎn)任何HTML!當(dāng)然PHP5本身就帶了不少DOM解析 庫(kù),QueryPath本身也是在這些庫(kù)上的二次加工,省下了我們不少的工作量。

QueryPath官方網(wǎng)站: http://querypath.org/

?

QueryPath使用一個(gè)qp()工廠函數(shù),為各種需求生成不同的類,一個(gè)最簡(jiǎn)單的例子如下:

?

    require 'QueryPath/QueryPath.php'; 
$html = qp('a.html');
$html->find('title')->text('hello world');
$html->find('.myInput')->attr('value', 'hello world');
$html->find('body')->css('background-color', 'red');
  
?

如果你對(duì)jQuery熟悉的話,幾乎可以沒(méi)有任何學(xué)習(xí)成本就能很快上 手。我立刻就使用QueryPath來(lái)寫(xiě)了幾個(gè)測(cè)試?yán)蹋治龊捅闅v了一個(gè)常去的網(wǎng)站的內(nèi)容結(jié)構(gòu),抓取了和分析了不少有用的資料。感覺(jué)對(duì)于那些做網(wǎng)站采集 程序的家伙們來(lái)說(shuō),QueryPath是不是又要讓他們更加如魚(yú)得水(抑或是無(wú)惡不作)了,LOL。

?

使用過(guò)程中發(fā)現(xiàn)QueryPath庫(kù)尚處于基本的開(kāi)發(fā)狀態(tài),不少問(wèn)題。但對(duì)于程序員來(lái)說(shuō),遇到問(wèn)題讀一下庫(kù)的源代碼,基本上就能搞定。下面列出兩個(gè) 常用問(wèn)題的解決,與大家分享。

?

1.當(dāng)QueryPath查詢到一個(gè)節(jié)點(diǎn)并操作完成后,它本身并不回到根節(jié)點(diǎn),而是停留在節(jié)點(diǎn)上,不知道這樣描述正確否,這樣導(dǎo)致的結(jié)果是下一步的 查詢將很可能找不到數(shù)據(jù)。解決的方法是用top()函數(shù)回到根節(jié)點(diǎn)。如上面的例子可以直接這樣用,用top回到根:

?

    $html->top()->find('.myInput')->attr('value', 'hello world');
  
?

支持的方法有top(), prev(), next(), child(),不用解釋,很好理解。

?

?

2.無(wú)法讀取遠(yuǎn)程url,或不能識(shí)別非"html"的擴(kuò)展名的html文件。QueryPath直接分析文件和url的擴(kuò)展名,不為"html"的直接當(dāng)做xml處理,寒一個(gè)。解決的辦法是用url的傳遞參數(shù)在最后面?zhèn)窝b一 個(gè)".html"的參數(shù),告訴QueryPath這是HTML文件。解決方法:

?

    $qp('http://www.acwind.net/index.php?=.html');//偽裝一個(gè)后綴名,搞定。
  
?

希望開(kāi)發(fā)者能在將來(lái)的版本中改進(jìn),能自動(dòng)識(shí)別文件類型那該多好。


詳解:

?

PHP 也曾在 Web 開(kāi)發(fā)領(lǐng)域造成轟動(dòng)。由于易于開(kāi)發(fā)和以 Web 為中心的模型,PHP 使 Web 站點(diǎn)從小小的主頁(yè)變成像 Yahoo! 這樣強(qiáng)大的站點(diǎn)。但是,通過(guò) PHP 來(lái)使用這三種技術(shù) — 尤其是 XML — 有時(shí)候會(huì)比較復(fù)雜。在本文中,了解 QueryPath,這是一個(gè) PHP 庫(kù),它在設(shè)計(jì)時(shí)考慮了兩個(gè)目標(biāo):

  • 簡(jiǎn)單性,使 HTML、XML 和 HTTP 變得容易使用
  • 健壯性,為使用這些技術(shù)提供豐富的工具

本文探索如何構(gòu)建 QueryPath 對(duì)象、遍歷 XML 和 HTML、操縱 XML 和 HTML 以及使用 QueryPath 訪問(wèn) Web 服務(wù)(使用 Twitter 作為示例服務(wù))。

?


剖析 QueryPath 鏈

?

對(duì)于 QueryPath 的典型使用,有四個(gè)最重要的概念:

  • QueryPath 對(duì)象與一個(gè) XML 或 HTML 文檔相關(guān)聯(lián)。
  • QueryPath 可以查詢文檔,識(shí)別文檔中的一組匹配項(xiàng)。
  • QueryPath 可以操縱文檔。可以添加新的部分,修改已有的部分,刪除不想要的部分。
  • QueryPath 方法可以鏈接在一起,在一個(gè)簡(jiǎn)潔的序列中執(zhí)行很多操作。只需幾行代碼,就可以裝載、解析、查詢、修改和寫(xiě)入文檔。

清單 1 中的代碼展示了所有這些要點(diǎn)。


清單 1. 基本的 QueryPath 鏈

?

    <?php
require 'QueryPath/QueryPath.php';
qp('sample.html')->find('title')->text('Hello World')->writeHTML();
?>
  
? ?

以上例子需要一個(gè)庫(kù),即 QueryPath/QueryPath.php 。除非還要裝載 QueryPath 擴(kuò)展,否者只需包括這個(gè)庫(kù)就可以使用 QueryPath。

PHP 對(duì)象語(yǔ)法
具有面向過(guò)程編程背景的 PHP 開(kāi)發(fā)人員可能不熟悉 PHP 的面向?qū)ο笳Z(yǔ)法。一個(gè)對(duì)象可能有一些附屬的函數(shù)。這些函數(shù)稱作 方法(method) 。可以通過(guò) 對(duì)象操作符 (->)調(diào)用 對(duì)象的方法。

例子中接下來(lái)一行代碼是一個(gè) QueryPath 鏈,它做以下事情。

  1. 創(chuàng)建一個(gè)新的 QueryPath 對(duì)象,該對(duì)象指向 sample.html 文檔。當(dāng) qp() 運(yùn)行時(shí),它將創(chuàng)建一個(gè)新的 QueryPath 對(duì)象,后者隨即裝載和解析文檔。
  2. 使用 find() 方法,它使用 CSS 3 選擇器 title 搜索整個(gè)文檔,尋找所有 <title/> 元素。

    在一個(gè)有效的 HTML 文檔中,該搜索只能在文檔的頭部找到一個(gè)匹配的 <title/> 元素。

  3. 標(biāo)題的文本值被設(shè)為 Hello World 。當(dāng)執(zhí)行到這里時(shí),標(biāo)題的子節(jié)點(diǎn)將被 CDATA(字符數(shù)據(jù))字符串 Hello World 替換。任何已有的內(nèi)容將被破壞。
  4. 使用 writeHTML() 方法將整個(gè)文檔寫(xiě)到標(biāo)準(zhǔn)輸出中。

以上例子實(shí)際上還可以縮短一點(diǎn),因?yàn)? qp() 工廠函數(shù)帶有一個(gè) CSS 選擇器作為可選的第二個(gè)參數(shù)。清單 2 顯示了縮短后的版本。


清單 2. 基本的 QueryPath 鏈縮短后的版本

?

            <?php
require 'QueryPath/QueryPath.php';

qp('sample.html', 'title')->text('Hello World')->writeHTML();
?>
          
?

?

假設(shè) sample.html 是一個(gè)最基本的 HTML 文檔,以上代碼( 清 單 1 或清單 2)的結(jié)果看上去將如清單 3 所示。加粗的行包含我們?cè)O(shè)置的標(biāo)題。


清單 3. 生成的 HTML 的例子

?

            <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
  "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
	<title>Hello World</title>

</head>
<body>
</body>
</html>
          
?

?

這些簡(jiǎn)單的例子展示了 QueryPath 可以執(zhí)行的一些常見(jiàn)的任務(wù)。接下來(lái)幾個(gè)小節(jié)探索一些方法。然后,您將把這些構(gòu)建塊裝配起來(lái),創(chuàng)建一個(gè)簡(jiǎn)單的 Web 服務(wù)客戶機(jī)。

?

qp() 工廠函數(shù)

?

QueryPath 庫(kù)中最常用的函數(shù)是 qp() 工廠函數(shù)。實(shí)際上,它執(zhí)行創(chuàng)建新的 QueryPath 對(duì)象的任務(wù)。它被用于傳統(tǒng)的構(gòu)造函數(shù)。

?

如果您熟悉面向?qū)ο笤O(shè)計(jì)模式,那么可能會(huì)意識(shí)到 qp() 是工廠模式的一個(gè)變種。 QueryPath 不是用構(gòu)造器方法定義一個(gè)工廠類,而是使用一個(gè)函數(shù)。這種方法除了可以節(jié)省鍵盤輸入外(在鏈接方法時(shí)比較重要),還可以使 QueryPath 更貼近 jQuery,減少 jQuery 熟悉者的學(xué)習(xí)曲線。

?

一個(gè) QueryPath 對(duì)象與一個(gè) XML 或 HTML 文檔相關(guān)聯(lián)。當(dāng)構(gòu)造 QueryPath 對(duì)象時(shí),文檔被綁定到該對(duì)象。 qp() 函數(shù)帶有 3 個(gè)參數(shù),這 3 個(gè)參數(shù)都是可選的:

一個(gè)文檔
可以是一個(gè)文件名或 URL、一個(gè) XML 或 HTML 字符串、一個(gè) DOMDocument 或 DOMElement、一個(gè) SimpleXMLElement 或者一個(gè) DOMElement 數(shù)組。如果不為該參數(shù)提供任何值,QueryPath 將創(chuàng)建一個(gè)空白的 XML 文檔,供后面進(jìn)行操縱。

一個(gè) CSS3 選擇器
如果提供了該參數(shù),在裝載文檔時(shí),QueryPath 將使用給定的選擇器查詢那個(gè)文檔。

一個(gè)關(guān)聯(lián)的選項(xiàng)數(shù)組
為這個(gè)特定 QueryPath 實(shí)例提供一種傳遞一組復(fù)雜配置參數(shù)的方法。API 參考詳細(xì)列出了這里可以傳遞的選項(xiàng)。
XML 還是 HTML?
QueryPath 既可以處理 XML,也可以處理 HTML,但這兩種格式有些區(qū)別。 QueryPath 試圖自動(dòng)檢測(cè)所使用的格式,并作出相應(yīng)的調(diào)整。XHTML(用 XML 實(shí)現(xiàn)的 HTML)被視作 XML。

qp() 支持將很多類型的數(shù)據(jù)作為第一個(gè)參數(shù),從而方便構(gòu)建 QueryPath 對(duì)象。QueryPath 可以以一個(gè)文件名或 URL 開(kāi)始,然后裝載一個(gè)文檔。如果傳遞的是一個(gè) XML 或 HTML 字符串,QueryPath 將解析該內(nèi)容。當(dāng)然,它可以接受另外兩種常用的 XML 文檔的對(duì)象表示:DOM 和 SimpleXML。清單 4 展示 qp() 函數(shù)如何解析包含 XML 的字符串。


清單 4. 從 XML 字符串構(gòu)建 QueryPath 對(duì)象

?

            <?php
require 'QueryPath/QueryPath.php';

$xml = '<?xml version="1.0"?><doc><item/></doc>';
$qp  = qp($xml);
?>
          
?

?

當(dāng)清單 4 中的代碼運(yùn)行時(shí), $qp 將引用一個(gè) QueryPath 對(duì)象,該對(duì)象在內(nèi)部指向 XML 解析后的表示。前面的例子傳入的是一個(gè)文件名。如果 PHP 被配置為允許 HTTP/HTTPS 流包裝器(在大多數(shù) PHP V5 發(fā)行版中是標(biāo)準(zhǔn)配置),那么甚至可以裝載遠(yuǎn)程 HTTP URL,如下所示。


清單 5. 從 URL 構(gòu)建 QueryPath 對(duì)象

?

            <?php
require 'QueryPath/QueryPath.php';

$qp = qp('http://example.com/file.xml');
?>
          
?

?

這樣便可以使用 QueryPath 訪問(wèn) Web 服務(wù)。(可以使用第 3 個(gè)參數(shù) qp() 傳遞流上下文,以便對(duì)連接設(shè)置進(jìn)行調(diào)整)。當(dāng)創(chuàng)建新文檔時(shí),有一個(gè)添加樣板 HTML 的快捷方式,如下所示。


清單 6. 使用 QueryPath::HTML_STUB 常量

?

            <?php
require 'QueryPath/QueryPath.php';

$qp = qp(QueryPath::HTML_STUB);
?>
          
?

?

QueryPath::HTML_STUB 常量定義一個(gè)基本的 HTML 文檔,如下所示。


清單 7. QueryPath::HTML_STUB 文檔

?

            <?xml version="1.0"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
	<title>Untitled</title>
</head>
<body></body>
</html>
          
?

?

以這個(gè)框架文檔為基礎(chǔ),可以更快地生成 HTML。

至此,您知道了如何創(chuàng)建新的指向文檔的 QueryPath 對(duì)象,并且看到了一個(gè)簡(jiǎn)單的 CSS 選擇器。下一小節(jié)討論如何使用 QueryPath 遍歷文檔。

?

遍歷文檔

?

打開(kāi)文檔后,需要在文檔中查找感興趣的內(nèi)容。QueryPath 的設(shè)計(jì)使得這一任務(wù)變得很容易。為了簡(jiǎn)化遍歷需求,QueryPath 提供了一些用于遍歷的方法。大多數(shù)方法使用 CSS3 選擇器查找所需的節(jié)點(diǎn)。


圖 1. 重要的 QueryPath 遍歷方法
重要的 QueryPath 遍歷方法

圖 1 總結(jié)了常用的遍歷函數(shù)。下面一一描述每個(gè)函數(shù)。雖然還有一些遍歷函數(shù)沒(méi)有提到,但這里覆蓋了大多數(shù)常見(jiàn)的需求。

?

表 1. 常見(jiàn)遍歷方法

方法 描述 是否帶 CSS 選擇器
find() 選擇與選擇器匹配的任何元素(在當(dāng)前選擇的節(jié)點(diǎn)下)
xpath() 選擇與給定 XPath 查詢匹配的元素 否(使用 XPath 查詢)
top() 選擇文檔元素(根元素)
parents() 選擇任何祖先元素
parent() 選擇直接父元素
siblings() 選擇所有同胞(sibling)元素(包括之前和之后的元素)
next() 選擇后一個(gè)同胞元素
nextAll() 選擇當(dāng)前元素之后的所有同胞元素
prev() 選擇前一個(gè)同胞元素
prevAll() 選擇當(dāng)前元素之前的所有同胞元素
children() 選擇當(dāng)前元素的直接子元素
deepest() 選擇當(dāng)前元素下最深的節(jié)點(diǎn)

?

QueryPath 中的很多方法可以以查詢作為參數(shù),進(jìn)一步指定應(yīng)該選擇什么項(xiàng)。如表 1 中第三列所示,幾乎所有這些方法都帶有一個(gè)作為可選參數(shù)的 CSS3 選擇器。( xpath() 函數(shù)則帶有一個(gè) XPath 查詢,而不是 CSS3 選擇器)。只有 top() deepest() 不使用查詢作為參數(shù)。

可以通過(guò)另一個(gè)簡(jiǎn)單的例子了解如何進(jìn)行遍歷。假設(shè)有一個(gè)像下面這樣的 XML 文檔。


清單 8. 一個(gè)簡(jiǎn)單的 XML 文檔

?

            <?xml version="1.0"?>
<root>
  <child id="one"/>
  <child id="two"/>
  <child id="three"/>
  <ignore/>
</root>            
          
?

?

<root/> 元素有 4 個(gè)子元素:其中有 3 個(gè)名為 <child/> ,還有一個(gè)名為 <ignore/> 。可以用一個(gè) QueryPath 查詢選擇 <root/> 的所有 4 個(gè)子元素。


清單 9. 選擇所有子元素

?

            <?php 
require 'QueryPath/QueryPath.php';

$xml = '<?xml version="1.0"?>
<root>
  <child id="one"/>
  <child id="two"/>
  <child id="three"/>
  <ignore/>
</root>';

$qp = qp($xml, 'root')->children();
print $qp->size();
?>
          
?

?

children() 方法將選擇 <root/> 元素的所有直接子元素。最后一行打印 QueryPath 對(duì)象中匹配項(xiàng)的數(shù)量,最終打印的結(jié)果為 4

假設(shè)只需選擇 3 個(gè) <child/> 元素,而不需要選擇 <ignore/> 元素。 清單 10 顯示了如何實(shí)現(xiàn)這一點(diǎn)。


清單 10. 使用過(guò)濾器的查詢

?

            <?php 
require 'QueryPath/QueryPath.php';

$xml = '<?xml version="1.0"?>
<root>
<child id="one"/>
<child id="two"/>
<child id="three"/>
<ignore/>
</root>';

$qp = qp($xml, 'root')->children('child');

print $qp->size();
?>
          
?

?

最后的 print 語(yǔ)句將打印 QueryPath 當(dāng)前選擇的項(xiàng)的數(shù)量。它將返回 3 。在內(nèi)部,QueryPath 跟蹤這 3 個(gè)元素。它們被存儲(chǔ)為當(dāng)前上下文。如果執(zhí)行進(jìn)一步的查詢,那么查詢將從這 3 個(gè)元素開(kāi)始。如果試圖附加數(shù)據(jù),那么數(shù)據(jù)將被附加到這 3 個(gè)元素后。

CSS 選擇器

CSS 屬性
CSS3 選擇器將一些屬性視作專用屬性。 id class 屬性都有專用的選擇器語(yǔ)法。與其他 XML 技術(shù)不同,XML DTD 或模式不需要將這些屬性指定為專用屬性。這些屬性仍是由 CSS3 選擇器引擎處理。

CSS 選擇器是 CSS 語(yǔ)句的一部分,用于選擇將應(yīng)用某種樣式的元素。CSS 選擇器還可以在樣式表上下文之外使用。QueryPath 使用選擇器作為查詢語(yǔ)言,并支持 CSS3 選擇器 標(biāo) 準(zhǔn) 中描述的特性集。

CSS 選擇器在 QueryPath 中扮演很重要的角色。您已經(jīng)看到,有 10 個(gè)函數(shù)使用 CSS 選擇器作為參數(shù)。到目前為止使用的選擇器是簡(jiǎn)單的標(biāo)記名查詢。CSS3 選擇器要比前面的例子強(qiáng)大得多。對(duì) CSS3 選擇器的詳細(xì)描述超出了本文的范圍,但表 2 提供了一些常見(jiàn)的選擇器模式的例子。


表 2. 常見(jiàn)的 CSS3 選擇器模式

選擇器模式 描述 示例匹配項(xiàng)
p 找到標(biāo)記名為 <p/> 的元素 <p>
.container 找到 class 屬性被設(shè)為 container 的元素 <div class="container"/>
#menu 找到 id 屬性被設(shè)為 menu 的元素。基于 ID 的搜索以這種方式進(jìn)行 <div id="menu"/>
[type="inline"] 找到 type 屬性的值為 inline 的元素 <code type="inline"/>
tr > th 找到直接父元素為 <tr> <th> 元素 <tr><th/></tr>
table td 找到祖先(例如父親或祖父)中有 <table> 元素的 <td> 元素 <table><tr><td/></tr></table>
li:first 獲取第一個(gè)名為 <li/> 的元素。支持的偽類包括 :last :even :odd <li/>
RDF|seq 找到 <RDF:seq> 元素。 QueryPath 包括用于 XML 名稱空間的 CSS3 選擇器。名稱空間支持延伸到屬性和元素 <RDF:seq>

?

這些常見(jiàn)的選擇器模式可以加以組合,形成復(fù)雜的選擇器,例如

?

            div.content ul>li:first
          
?


。 這個(gè)選擇器將搜索 class 為 content 的任何 <div/> 。 在 div 中,它將搜索所有無(wú)序列表( <ul> ),返回每個(gè)列表的第一個(gè)列表項(xiàng)( <li> )。

?

迭代匹配項(xiàng)

?

您了解了遍歷文檔的兩個(gè)方面:QueryPath 提供的方法和 CSS3 選擇器支持。第三個(gè)方面是迭代選擇的項(xiàng)。

QueryPath 對(duì)象是 可遍歷的(traversable) 。在 PHP 中,這意味著對(duì)象可以當(dāng)做迭代器。標(biāo)準(zhǔn)的 PHP 循環(huán)結(jié)構(gòu)可以遍歷 QueryPath 對(duì)象選擇的元素。還記得嗎, 清 單 10 中的例子是一個(gè)簡(jiǎn)單的查詢,它從一個(gè) XML 文檔中檢索 3 個(gè)元素。接下來(lái)的例子將以這個(gè)例子為基礎(chǔ)。

如果要單獨(dú)處理每個(gè)項(xiàng),應(yīng)該怎么辦?很容易,因?yàn)?QueryPath 可以用作迭代器。清單 11 顯示了一個(gè)例子。


清單 11. 迭代選擇的元素

?

            <?php 
require 'QueryPath/QueryPath.php';

$xml = '<?xml version="1.0"?>
<root>
<child id="one"/>
<child id="two"/>
<child id="three"/>
<ignore/>
</root>';

$qp = qp($xml, 'root')->children('child');

foreach ($qp as $child) {
  print $child->attr('id') . PHP_EOL;
}
?>
          
?

?

當(dāng) foreach 循環(huán)迭代時(shí),它將每個(gè)匹配項(xiàng)賦給 $child 變量。但是, $child 不是真正的元素,它是指向當(dāng)前元素的一個(gè) QueryPath 對(duì)象。您可以任意使用所有常見(jiàn)的 QueryPath 方法。

?

為了使 API 與 jQuery 的 API 類似, QueryPath 提供一些可同時(shí)作為 accessor 和 mutator — 或 getter 和 setter 的方法。取決于參數(shù),同一個(gè)方法可以檢索(access)數(shù)據(jù),或者更改(mutate)數(shù)據(jù)。 attr() 函數(shù)就是一個(gè)例子。

?

qp()->attr('name') 檢索 name 屬性的值。 qp()->attr('name', 'value') name 屬性的值設(shè)為 value 。還有一些方法,包括 text() html() xml() ,作為 accessor 和 mutator 同時(shí)執(zhí)行兩種任務(wù)。

?

由于每個(gè)迭代的項(xiàng)包裝在一個(gè) QueryPath 對(duì)象中,所以可以通過(guò) $child 任意使用所有標(biāo)準(zhǔn)的 QueryPath 方法。上面的例子使用了 attr() 函數(shù),這是一個(gè)元素中的屬性的 accessor 和 mutator。

attr() 方法檢索名為 id 的屬性的值。下面顯示以上代碼的輸出。


清單 12. 清單 11 中迭代器例子的輸出

?

            one
two
three
          
?

?

您已經(jīng)了解了如何使用 QueryPath 方法、CSS3 選擇器和迭代技術(shù)遍歷文檔。下一節(jié)探索如何用 QueryPath 修改文檔。

?

操縱文檔

?

除了使用 QueryPath 搜索文檔外,還可以使用它添加、修改和移除文檔中的數(shù)據(jù)。在清單 1 中可以大致了解 QueryPath 的功能。為了方便,下面再重復(fù)一遍。


清單 13. 基本的 QueryPath 鏈

?

            <?php
require 'QueryPath/QueryPath.php';

qp('sample.html')->find('title')->text('Hello World')->writeHTML();
?>
          
?

?

在這個(gè)例子中, text() 函數(shù)用于修改 <title/> 元素的內(nèi)容。QueryPath 提供了十幾個(gè)用于更改文檔的方法。圖 2 展示一些常用的修改方法如何工作。這些方法都是添加或替換數(shù)據(jù)。綠色的標(biāo)記表示當(dāng)前被選中的元素。


圖 2. 用于添加或替換內(nèi)容的 QueryPath 方法


用于添加或替換內(nèi)容的 QueryPath 方法

每個(gè)方法以字符串?dāng)?shù)據(jù)(通常是以 HTML 或 XML 片段的形式)作為參數(shù),并將數(shù)據(jù)插入到文檔中。隨后立即可以訪問(wèn)和進(jìn)一步操縱新插入的數(shù)據(jù)。

?

使用 HTML 和 XML 片段

實(shí)際上有兩類方法。第一類方法使用任意的 XML 片段,如下所示。

append() 將數(shù) 據(jù)添加為當(dāng)前選中元素的 最后一個(gè) 子元素
prepend() 將 數(shù)據(jù)添加為當(dāng)前選中元素的 第一個(gè) 子元素
after() 將 數(shù)據(jù)直接插在當(dāng)前選中元素 之后
before() 將數(shù)據(jù)直接插在當(dāng)前選擇的元素 之前
html() 替換 HTML 文檔中當(dāng)前元素的子內(nèi)容
xml() 替換 XML 文檔中當(dāng)前元素的子內(nèi)容

?

以上方法需要一個(gè)參數(shù),該參數(shù)包含一個(gè)格式良好的 XML 或 HTML 數(shù)據(jù)的字符串。清單 14 有一個(gè)使用 html() 方法的例子。


清單 14. 基本的 QueryPath 鏈

?

            <?php
require 'QueryPath/QueryPath.php';

qp($file)->find('div.content')->html('<ul><li>One</li></ul>');
?>
          
?

?

圖 2 中沒(méi)有給出 remove() 方法(難以清楚地表示移除)。 remove() 方法移除文檔中的元素。如果不帶參數(shù)調(diào)用,該方法將移除當(dāng)前選中的元素。但是,和很多其他的 QueryPath 方法一樣, remove() 可以使用一個(gè) CSS3 選擇器作為可選參數(shù)。如果提供了一個(gè)選擇器,那么只移除與選擇器匹配的項(xiàng)。

?

使用屬性

圖 2 中的第二類方法則操縱元素中的屬性。下面介紹兩個(gè)這樣的例子。

attr() 獲取或設(shè) 置每個(gè)選中的元素上給定屬性的值
addClass() 為當(dāng)前選中的每 個(gè)元素添加一個(gè)類

?

還有其他一些與屬性相關(guān)的方法。例如 removeClass() 方法,該方法以一個(gè)類名作為參數(shù),它將移除元素中的一個(gè)類。 removeAttr() 以一個(gè)屬性名作為參數(shù),它將從所有當(dāng)前選中的元素中移除具有該名稱的屬性。

現(xiàn)在可以將所有這些基本功能組合到一起,形成有趣的東西。

?

示例:用 QueryPath 搜索 Twitter

?

Twitter 是一個(gè)流行的微博客服務(wù),通過(guò)它可以發(fā)布短消息,同時(shí)還可以跟隨其他 Twitter 用戶的微博客。 Twitter 提供了一個(gè)簡(jiǎn)單的 Web 服務(wù),用于公布該平臺(tái)的很多特性。

?

下面的例子使用 QueryPath 在 Twitter 服務(wù)器上執(zhí)行搜索,并以 HTML 格式打印結(jié)果。可以將一個(gè)工具添加到已有的 Web 站點(diǎn),以顯示最近的關(guān)于一個(gè)感興趣的話題的 Twitter 活動(dòng)。

?

Twitter 的搜索服務(wù)器偵聽(tīng)一個(gè)標(biāo)準(zhǔn)的 HTTP 服務(wù)器,當(dāng)被請(qǐng)求時(shí),以 Atom XML 格式返回搜索結(jié)果。我們的例子將搜索最近 5 個(gè)提到 QueryPath 的貼子。為了運(yùn)行這種搜索,并以 Atom 格式返回內(nèi)容,只需在 URL 中編寫(xiě)必要的信息: http://search.twitter.com/search. atom ? rpp=5 & q=QueryPath

加粗的 3 個(gè)部分表示針對(duì)這個(gè)應(yīng)用程序進(jìn)行了調(diào)整的參數(shù)。

?

.atom 提供這個(gè)擴(kuò) 展名是為了告訴服務(wù)器需要返回 Atom XML 內(nèi)容
rpp=5 RPP 指定每頁(yè)顯示的結(jié)果數(shù)。我們想要返回 5 條結(jié)果。默認(rèn)情況下,將返回 5 條最近的結(jié)果
q=QueryPath 這 是查詢。Twitter 支持更復(fù)雜的搜索查詢,但對(duì)于這個(gè)簡(jiǎn)單的例子只需要這樣的查詢。

?

當(dāng)裝載這個(gè) URL 時(shí),Twitter 將返回一個(gè) Atom 格式的 XML 文檔。下面的清單 15 顯示一個(gè)經(jīng)過(guò)大量簡(jiǎn)化的返回文檔。這里只顯示最關(guān)心的信息(只顯示一個(gè)條目)。


清單 15. Twitter 搜索返回的 XML 的摘錄

?

            <?xml version="1.0" encoding="UTF-8"?>
<feed>
  <entry>
    <content type="html">
       Last night I added XSD schema validation and XSL
       Transformation (XSLT) support to &lt;b&gt;QueryPath&lt;/b&gt; (as
       extensions). Will commit them today.
    </content>
    <link type="image/png" rel="image" />
    <author>
      <name>technosophos (M Butcher)</name>
      <uri>http://twitter.com/technosophos</uri>
    </author>
  </entry>
</feed>
          
?

?

清單 16 顯示了執(zhí)行搜索的簡(jiǎn)要的 QueryPath 代碼,處理返回的 XML,并創(chuàng)建一個(gè)文檔。


清單 16. 用 QueryPath 處理返回的 XML

?

            <?php
require 'QueryPath/QueryPath.php';

$url = 'http://search.twitter.com/search.atom?rpp=5&q=QueryPath';
$out = qp(QueryPath::HTML_STUB, 'body')->append('<ul/>')->find('ul');

foreach (qp($url, 'entry') as $result) {
  $title = $result->children('content')->text();
  $img = $result->siblings('link[rel="image"]')->attr('href');
  $author = $result->parent()->find('author>name')->text();
  $out->append("<li><img src='$img'/> <em>$author</em><br/>$title</li>");
}
$out->writeHTML();
?>
          
?

?

如果使用 Web 瀏覽器執(zhí)行以上代碼,可以看到圖 3 所示的結(jié)果。


圖 3. QueryPath 顯示 Twitter 搜索結(jié)果


QueryPath 顯示 Twitter 搜索結(jié)果

清 單 16 中的代碼有 14 行,其中只有 9 行代碼做實(shí)際的工作。以上代碼是如何產(chǎn)生圖 3 中的視圖的呢?

?

$url 變量存放前面提到的 Twitter URL。 $out 變量指向用于將 HTML 寫(xiě)到客戶機(jī)的 QueryPath 對(duì)象。 從一個(gè)基本的文檔 ( QueryPath::HTML_STUB )開(kāi)始,添加一個(gè)無(wú)序列表,并(使用 find() ) 選擇這個(gè)新列表。

?

foreach 循環(huán)是腳本中最重要的一行: foreach (qp($url, 'entry') as $result) 。這里創(chuàng)建 一個(gè)新的 QueryPath 對(duì)象。由于傳遞了一個(gè) URL,QueryPath 將檢索遠(yuǎn)程 Atom 文檔,并解析結(jié)果。另外,由于傳遞了選擇器 entry ,QueryPath 將選擇文檔中的所有條目。回頭查看一下 清 單 15 ,看看這是文檔中的哪個(gè)部分。返回的文檔中將有 5 個(gè)條目(因?yàn)?URL 中這樣設(shè)置了 rpp 標(biāo)志)。這 5 個(gè)條目中的每個(gè)條目看上去都應(yīng)該與清單 15 中的 <entry/> 類似。

?

循環(huán)獲取了 3 個(gè)數(shù)據(jù)部分:

$title 條目的內(nèi) 容
$img 發(fā)帖用戶的頭像的 URL
$author 發(fā) 帖用戶的用戶名

?

為了獲取每塊數(shù)據(jù),可以使用不同的 QueryPath 方法。例如,可以使用 $result->children('content')->text(); 獲得 $title

?

使用 text() html() xml() 訪問(wèn)內(nèi)容
您看到了如何使用 text() 設(shè)置文本( 清 單 1 )。 清 單 16 中則使用該方法 獲取 信息。 text() 函數(shù)將返回所有文本內(nèi)容,但是不包括元素或其他節(jié)點(diǎn)類型。如果要獲得所有內(nèi)容,可以使用 xml() ,對(duì)于 HTML 文檔,則可以使用 html()

循環(huán)中首先選擇標(biāo)記名為 content 的所有子元素,然后從發(fā)現(xiàn)的節(jié)點(diǎn)中獲得 CDATA 文本。每個(gè)條目將有一個(gè) <content/> 元素。

?

現(xiàn)在需要獲得圖像 URL。在前面的鏈中,選擇了 <content/> 元素,所以這就是起點(diǎn)。現(xiàn)在需要搜索 <content/> 的同胞,找到形如 <link rel="image"/> 的元素。 為此,使用 siblings() 函數(shù),并提供一個(gè)選擇器作為參數(shù)。然后使用 attr() 函數(shù)獲得元素的 href 屬性的值。

?

最后,從 <link/> 元素跳回到它的父元素,接著使用 find('author>name') , 獲得作者的用戶名。(請(qǐng)查看 表 2 )。在這里,可以使用 text() 獲得作者的用戶名的文本。

?

foreach 循環(huán)的每次迭代的最后,構(gòu)建一個(gè) HTML 片段,并使用 append() 將這個(gè)片段插入到 $out QueryPath 中。

?

迭代完從 Twitter 返回的結(jié)果后,可以在腳本的最后將 HTML 文檔寫(xiě)到瀏覽器: $out->writeHTML();

這樣就完成了。在大約十幾行代碼中,您完成了與一個(gè)遠(yuǎn)程服務(wù)的交互。可以通過(guò)這種方式,使用 QueryPath 訪問(wèn)任何使用 HTTP 和 XML 或 HTML 的 Web 服務(wù)。QueryPath 附帶的例子展示了如何設(shè)置連接參數(shù)、對(duì) SPARQL 端點(diǎn)執(zhí)行 SPARQL 查詢以及解析復(fù)雜的、多名稱空間的文檔。QueryPath 為使用 Web 服務(wù)帶來(lái)巨大的潛力。

?

?

結(jié)束語(yǔ)

?

在本文中,您探索了 QueryPath 庫(kù)的基礎(chǔ)。您學(xué)習(xí)了如何創(chuàng)建 QueryPath 對(duì)象、遍歷文檔和操縱內(nèi)容。您還構(gòu)建了一個(gè)小型的例子腳本,該腳本使用流行的 Twitter 微博客服務(wù)的 Web 服務(wù) API。

?

本文只是初步發(fā)掘 QueryPath 庫(kù)的一些可能的應(yīng)用。例如,本文只提到數(shù)據(jù)庫(kù) API,可使用該 API 將 RDBMS 支持集成到 QueryPath。想象一下,運(yùn)行一個(gè) SQL SELECT 語(yǔ)句,并將結(jié)果直接合并到一個(gè)符合自己的規(guī)范的 HTML 表格中。或者再想象一下,構(gòu)建一個(gè) XML 導(dǎo)入器,用于解析數(shù)據(jù)并將數(shù)據(jù)直接插入到數(shù)據(jù)庫(kù)中。

?

QueryPath 還有一些特性這里沒(méi)有提到。通過(guò)映射器和過(guò)濾器,可以讓 QueryPath 運(yùn)行定制的函數(shù)來(lái)轉(zhuǎn)換或過(guò)濾 QueryPath 數(shù)據(jù)。通過(guò) QPTPL 擴(kuò)展,可以將數(shù)據(jù)插入到預(yù)定義的純 HTML 模板中。QueryPath 還支持用戶定義的擴(kuò)展。通過(guò)編寫(xiě)一個(gè)簡(jiǎn)單的類定義,可以將自己的方法添加到 QueryPath 中。

?

?

>>phpQuery—基于 jQuery的PHP實(shí)現(xiàn)

?

?

?

QueryPath, php上的jQuery


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 运城市| 娱乐| 田林县| 梁山县| 佛学| 扬中市| 玛多县| 阜平县| 固阳县| 秀山| 涿州市| 福泉市| 安福县| 邵东县| 长岭县| 巴楚县| 赣榆县| 六枝特区| 邹城市| 土默特右旗| 正阳县| 樟树市| 贵州省| 和政县| 玉山县| 长治市| 正阳县| 炎陵县| 灵武市| 高碑店市| 兴义市| 临西县| 锡林浩特市| 施甸县| 城固县| 雅江县| 思茅市| 丹巴县| 沛县| 宕昌县| 重庆市|