การแยกวิเคราะห์ XML ข้ามรายการที่คุณไม่ต้องการ

การแยกวิเคราะห์ XML หมายถึงการผ่านเอกสาร XML และส่งคืนข้อมูลที่เกี่ยวข้อง แม้ว่าบริการเว็บจำนวนมากขึ้นจะส่งคืนข้อมูลในรูปแบบ JSON แต่ส่วนใหญ่ยังคงใช้ XML อยู่ ดังนั้นจึงเป็นเรื่องสำคัญที่จะต้องแยกวิเคราะห์ XML หลัก หากคุณต้องการใช้ API ที่มีอยู่อย่างเต็มรูปแบบ

การใช้นามสกุล SimpleXMLใน PHP ซึ่งถูกเพิ่มกลับเข้ามาใน PHP 5.0 การทำงานกับ XML นั้นง่ายและสะดวกมาก ในบทความนี้ฉันจะแสดงวิธีการทำ

พื้นฐานการใช้งาน

มาเริ่มกันด้วยตัวอย่างต่อไปนี้ ภาษา.xml:


>

> 1972>
> Dennis Ritchie >
>

> 1995>
> ราสมุส เลอร์ดอร์ฟ >
>

> 1995>
> เจมส์ กอสลิ่ง >
>
>

เอกสาร XML นี้ประกอบด้วยรายการภาษาโปรแกรมพร้อมข้อมูลบางอย่างเกี่ยวกับแต่ละภาษา: ปีที่ดำเนินการและชื่อผู้สร้าง

ขั้นตอนแรกคือการโหลด XML โดยใช้ฟังก์ชั่นอย่างใดอย่างหนึ่ง simplexml_load_file(), หรือ simplexml_load_string(). ตามชื่อของฟังก์ชัน อันแรกจะโหลด XML จากไฟล์ และอันที่สองจะโหลด XML จากสตริง

ทั้งสองฟังก์ชันอ่านแผนผัง DOM ทั้งหมดลงในหน่วยความจำและส่งคืนอ็อบเจ็กต์ SimpleXMLElement. ในตัวอย่างข้างต้น ออบเจ็กต์ถูกเก็บไว้ในตัวแปรภาษา $ คุณสามารถใช้ฟังก์ชั่น var_dump()หรือ print_r()เพื่อรับข้อมูลโดยละเอียดเกี่ยวกับวัตถุที่ส่งคืน หากคุณต้องการ

SimpleXMLElement วัตถุ
[lang] => Array
[ 0 ] => SimpleXMLElementObject
[@attributes] => Array
[ชื่อ] => C
[ปรากฏตัว] => 1972
[ ผู้สร้าง] => Dennis Ritchie
[ 1 ] => SimpleXMLElement Object
[@attributes] => Array
[ชื่อ] => PHP
[ปรากฏ] => 1995
[ ผู้สร้าง] => ราสมุส เลอร์ดอร์ฟ
[ 2 ] => SimpleXMLElement Object
[@attributes] => Array
[name] => Java
[ปรากฏ] => 1995
[ ผู้สร้าง] => เจมส์ กอสลิง
)
)

XML นี้มีองค์ประกอบราก ภาษาซึ่งมีสามองค์ประกอบ แลงแต่ละองค์ประกอบอาร์เรย์สอดคล้องกับองค์ประกอบ ภาษาในเอกสาร XML

คุณสามารถเข้าถึงคุณสมบัติของวัตถุโดยใช้ตัวดำเนินการ -> . ตัวอย่างเช่น $languages->lang จะส่งคืนวัตถุ SimpleXMLElement ที่ตรงกับองค์ประกอบแรก ภาษา. วัตถุนี้มีสองคุณสมบัติ: ปรากฏและผู้สร้าง

$languages ​​​​-> lang [ 0 ] -> ปรากฏ ;
$languages ​​​​-> lang [ 0 ] -> ผู้สร้าง ;

แสดงรายการภาษาและแสดงคุณสมบัติของมันง่ายมากด้วยลูปมาตรฐานเช่น แต่ละ.

foreach ($languages ​​​​-> lang as $lang ) (
พิมพ์f(
"" ,
$lang["name"] ,
$lang -> ปรากฏ ,
$lang -> ผู้สร้าง
) ;
}

สังเกตว่าฉันเข้าถึงชื่อแอตทริบิวต์ขององค์ประกอบ lang เพื่อรับชื่อภาษาได้อย่างไร วิธีนี้คุณสามารถเข้าถึงแอตทริบิวต์ขององค์ประกอบที่แสดงเป็นวัตถุ SimpleXMLElement

การทำงานกับเนมสเปซ

ในขณะที่ทำงานกับ XML ของบริการเว็บต่างๆ คุณมักจะพบเนมสเปซขององค์ประกอบ มาเปลี่ยนของเรากันเถอะ ภาษา.xmlเพื่อแสดงตัวอย่างการใช้เนมสเปซ:



xmlns:dc =>

> 1972>
> Dennis Ritchie >
>

> 1995>
> ราสมุส เลอร์ดอร์ฟ >
>

> 1995>
> เจมส์ กอสลิ่ง >
>
>

ตอนนี้องค์ประกอบ ผู้สร้างวางไว้ในเนมสเปซ กระแสตรงซึ่งชี้ไปที่ http://purl.org/dc/elements/1.1/ หากคุณพยายามพิมพ์ผู้สร้างภาษาโดยใช้รหัสก่อนหน้าของเรา จะไม่ทำงาน ในการอ่านเนมสเปซขององค์ประกอบ คุณต้องใช้วิธีใดวิธีหนึ่งต่อไปนี้

วิธีแรกคือการใช้ชื่อ URI โดยตรงในโค้ดเมื่ออ้างถึงเนมสเปซขององค์ประกอบ ตัวอย่างต่อไปนี้แสดงวิธีการดำเนินการนี้:

$dc = $languages ​​​​-> lang [ 1 ] -> เด็ก ( "http://purl.org/dc/elements/1.1/") ;
echo $dc -> ผู้สร้าง ;

วิธี เด็ก()ใช้เนมสเปซและส่งคืนองค์ประกอบย่อยที่ขึ้นต้นด้วยคำนำหน้า ต้องใช้สองอาร์กิวเมนต์ อันแรกคือเนมสเปซ XML และอาร์กิวเมนต์ที่สองเป็นอาร์กิวเมนต์ทางเลือกที่มีค่าเริ่มต้นเป็น เท็จ. ถ้าอาร์กิวเมนต์ที่สองถูกตั้งค่าเป็น TRUE เนมสเปซจะถือเป็นคำนำหน้า หากเป็น FALSE เนมสเปซจะถือเป็นเนมสเปซ URL

วิธีที่สองคืออ่านชื่อ URI จากเอกสารและใช้เมื่ออ้างถึงเนมสเปซขององค์ประกอบ นี่เป็นวิธีที่ดีที่สุดในการเข้าถึงองค์ประกอบ เพราะคุณไม่จำเป็นต้องฮาร์ดโค้ดลงใน URI

$namespaces = $languages ​​​​-> getNamespaces (จริง) ;
$dc = $languages ​​​​-> lang [ 1 ] -> children ($namespaces [ "dc" ] ) ;

echo $dc -> ผู้สร้าง ;

วิธี รับเนมสเปซ ()ส่งคืนอาร์เรย์ของชื่อนำหน้าและ URI ที่เกี่ยวข้อง ใช้พารามิเตอร์เพิ่มเติมซึ่งมีค่าเริ่มต้นเป็น เท็จ. หากคุณติดตั้งเช่น จริงจากนั้นเมธอดนี้จะส่งคืนชื่อที่ใช้ในโหนดหลักและโหนดย่อย มิฉะนั้น จะพบเนมสเปซที่ใช้ในโหนดหลักเท่านั้น

ตอนนี้คุณสามารถทำซ้ำผ่านรายการภาษาดังนี้:

$languages ​​​​= simplexml_load_file ("languages.xml" );
$ns = $languages ​​​​-> getNamespaces (จริง) ;

foreach ($languages ​​​​-> lang as $lang ) (
$dc = $lang -> ลูก ($ns [ "dc" ] );
พิมพ์f(
"

%s ปรากฏใน %d และถูกสร้างขึ้นโดย %s

" ,
$lang["name"] ,
$lang -> ปรากฏ ,
$dc -> ผู้สร้าง
) ;
}

กรณีศึกษา - การแยกวิเคราะห์ช่องวิดีโอ YouTube

มาดูตัวอย่างที่ได้รับฟีด RSS จากช่อง YouTube และแสดงลิงก์ไปยังวิดีโอทั้งหมดจากช่องดังกล่าว โปรดติดต่อตามที่อยู่ต่อไปนี้:

http://gdata.youtube.com/feeds/api/users/xxx/uploads

URL ส่งคืนรายการวิดีโอล่าสุดจากช่องที่กำหนดในรูปแบบ XML เราจะแยกวิเคราะห์ XML และรับข้อมูลต่อไปนี้สำหรับแต่ละวิดีโอ:

  • ลิงก์ไปยังวิดีโอ
  • มินิมอล
  • ชื่อ

เราจะเริ่มต้นด้วยการค้นหาและโหลด XML:

$channel = "ชื่อช่อง" ;
$url = "http://gdata.youtube.com/feeds/api/users/". $ช่อง. "/อัพโหลด" ;
$xml = file_get_contents ($url ) ;

$feed = simplexml_load_string ($xml ) ;
$ns = $feed -> getNameSpaces (จริง) ;

หากคุณดูที่ฟีด XML คุณจะเห็นว่ามีองค์ประกอบหลายอย่าง นิติบุคคลซึ่งแต่ละรายการจะเก็บข้อมูลโดยละเอียดเกี่ยวกับวิดีโอเฉพาะจากช่อง แต่เราใช้เฉพาะภาพขนาดย่อ ที่อยู่วิดีโอ และชื่อเท่านั้น องค์ประกอบทั้งสามนี้เป็นลูกขององค์ประกอบ กลุ่มซึ่งเป็นลูกของ รายการ:

>

>



ชื่อ... >

>

>

เราจะผ่านทุกองค์ประกอบ รายการและดึงข้อมูลที่จำเป็นสำหรับแต่ละรายการ สังเกตว่า ผู้เล่น, รูปขนาดย่อและ ชื่ออยู่ในเนมสเปซสื่อ ดังนั้นเราต้องดำเนินการตามตัวอย่างที่แล้ว เราได้รับชื่อจากเอกสารและใช้เนมสเปซเมื่ออ้างถึงองค์ประกอบ

foreach ($feed -> รายการเป็น $entry ) (
$group = $entry -> เด็ก ($ns [ "media" ] );
$group = $group -> กลุ่ม ;
$thumbnail_attrs = $group -> ภาพขนาดย่อ [ 1 ] -> คุณลักษณะ () ;
$image = $thumbnail_attrs [ "url" ] ;
$player = $group -> ผู้เล่น -> คุณสมบัติ () ;
$link = $player["url"] ;
$title = $group -> ชื่อ;
พิมพ์f( "

" ,
$player , $image , $title ) ;
}

บทสรุป

ตอนนี้คุณรู้วิธีใช้แล้ว SimpleXMLในการแยกวิเคราะห์ข้อมูล XML คุณสามารถพัฒนาทักษะของคุณโดยแยกวิเคราะห์ฟีด XML ต่างๆ ด้วย API ที่แตกต่างกัน แต่สิ่งสำคัญคือต้องจำไว้ว่า SimpleXML อ่าน DOM ทั้งหมดลงในหน่วยความจำ ดังนั้น หากคุณกำลังแยกวิเคราะห์ชุดข้อมูลขนาดใหญ่ หน่วยความจำอาจไม่เพียงพอ หากต้องการเรียนรู้เพิ่มเติมเกี่ยวกับ SimpleXML โปรดอ่านเอกสารประกอบ


หากคุณมีคำถามใด ๆ โปรดใช้ .ของเรา

ตอนนี้เราจะศึกษาการทำงานกับ XML XML เป็นรูปแบบสำหรับการแลกเปลี่ยนข้อมูลระหว่างไซต์ มันคล้ายกับ HTML มาก มีเพียง XML ที่อนุญาตให้แท็กและแอตทริบิวต์ของตัวเอง

เหตุใด XML จึงจำเป็นสำหรับการแยกวิเคราะห์ บางครั้งมันเกิดขึ้นที่ไซต์ที่คุณต้องการแยกวิเคราะห์มี API ที่ช่วยให้คุณได้รับสิ่งที่คุณต้องการโดยไม่ต้องใช้ความพยายามมาก ดังนั้น แนะนำให้ทันที - ก่อนแยกวิเคราะห์ไซต์ ให้ตรวจสอบว่ามี API หรือไม่

API คืออะไร? นี่คือชุดของฟังก์ชันที่คุณสามารถส่งคำขอไปยังไซต์นี้และรับการตอบกลับที่ต้องการ คำตอบนี้มักมาในรูปแบบ XML มาเริ่มศึกษากันเลยดีกว่า

การทำงานกับ XML ใน PHP

สมมติว่าคุณมี XML อาจเป็นสตริง เก็บไว้ในไฟล์ หรือให้บริการตามคำขอไปยัง URL เฉพาะ

ให้ XML ถูกเก็บไว้ในสตริง ในกรณีนี้ คุณต้องสร้างวัตถุจากบรรทัดนี้โดยใช้ ใหม่ SimpleXMLElement:

$str = " Kolya 25 1000 "; $xml = ใหม่ SimpleXMLElement($str);

ตอนนี้เรามีในตัวแปร $xmlวัตถุที่มีการแยกวิเคราะห์ XML จะถูกเก็บไว้ โดยการเข้าถึงคุณสมบัติของอ็อบเจ็กต์นี้ คุณจะสามารถเข้าถึงเนื้อหาของแท็ก XML ได้ เป็นอย่างไร - เราจะวิเคราะห์ให้ต่ำลงเล็กน้อย

หาก XML ถูกเก็บไว้ในไฟล์หรือส่งคืนโดยการเข้าถึง URL (ซึ่งส่วนใหญ่มักเป็นกรณี) คุณควรใช้ฟังก์ชัน simplexml_load_fileซึ่งทำให้วัตถุเดียวกัน $xml:

Kolya 25 1000

$xml = simplexml_load_file (พาธไฟล์หรือ url);

วิธีการทำงาน

ในตัวอย่างด้านล่าง XML ของเราถูกจัดเก็บไว้ในไฟล์หรือ URL

ให้ XML ต่อไปนี้ได้รับ:

Kolya 25 1000

มาดูชื่อ อายุ และเงินเดือนของพนักงานกัน:

$xml = simplexml_load_file (พาธไฟล์หรือ url); echo $xml->ชื่อ; //แสดง "Kolya" echo $xml->age; //ผลลัพธ์ 25 echo $xml->เงินเดือน; // เอาต์พุต 1,000

อย่างที่คุณเห็น ออบเจ็กต์ $xml มีคุณสมบัติที่สอดคล้องกับแท็ก

คุณอาจสังเกตเห็นว่าแท็ก ไม่ปรากฏให้เห็นทั่วกัน เนื่องจากเป็นแท็กรูท คุณสามารถเปลี่ยนชื่อได้ ตัวอย่างเช่น to - และจะไม่มีอะไรเปลี่ยนแปลง:

Kolya 25 1000

$xml = simplexml_load_file (พาธไฟล์หรือ url); echo $xml->ชื่อ; //แสดง "Kolya" echo $xml->age; //ผลลัพธ์ 25 echo $xml->เงินเดือน; // เอาต์พุต 1,000

XML สามารถมีแท็กรูทได้เพียงแท็กเดียว เช่นเดียวกับแท็กรูท ใน HTML ธรรมดา

มาแก้ไข XML ของเราสักหน่อย:

Kolya 25 1000

ในกรณีนี้ เราได้รับสายของการโทร:

$xml = simplexml_load_file (พาธไฟล์หรือ url); echo $xml->worker->name; //แสดง "Kolya" echo $xml->worker->age; //เอาต์พุต 25 echo $xml->worker->เงินเดือน; // เอาต์พุต 1,000

การทำงานกับคุณสมบัติ

ให้ข้อมูลบางส่วนถูกเก็บไว้ในแอตทริบิวต์:

หมายเลข 1

$xml = simplexml_load_file (พาธไฟล์หรือ url); echo $xml->worker["name"]; //แสดง "Kolya" echo $xml->worker["age"]; //เอาต์พุต 25 echo $xml->worker["salary"]; //เอาต์พุต 1,000 echo $xml->worker; // พิมพ์ "หมายเลข 1"

แท็กที่มีขีดกลาง

ใน XML อนุญาตให้ใช้แท็ก (และแอตทริบิวต์) ที่มียัติภังค์ ในกรณีนี้ แท็กดังกล่าวสามารถเข้าถึงได้ดังนี้:

Kolya Ivanov

$xml = simplexml_load_file (พาธไฟล์หรือ url); echo $xml->worker->(ชื่อจริง); //แสดง "Kolya" echo $xml->worker->(นามสกุล); // แสดง "Ivanov"

วนซ้ำ

ให้ตอนนี้เราไม่มีคนงานคนเดียว แต่มีหลายคน ในกรณีนี้ เราสามารถวนซ้ำวัตถุของเราด้วย foreach loop:

Kolya 25 1000 วาสยา 26 2000 ปีเตอร์ 27 3000

$xml = simplexml_load_file (พาธไฟล์หรือ url); foreach ($xml เป็น $worker) ( echo $worker->name; // พิมพ์ "Kolya", "Vasya", "Petya" )

จากอ็อบเจ็กต์เป็นอาร์เรย์ปกติ

หากคุณรู้สึกไม่สบายใจในการทำงานกับอ็อบเจ็กต์ คุณสามารถแปลงอ็อบเจ็กต์เป็นอาร์เรย์ PHP ปกติได้โดยใช้เคล็ดลับต่อไปนี้:

$xml = simplexml_load_file (พาธไฟล์หรือ url); var_dump(json_decode(json_encode($xml) จริง));

ข้อมูลมากกว่านี้

การแยกวิเคราะห์ตาม sitemap.xml

บ่อยครั้ง ไซต์มีไฟล์ sitemap.xml ไฟล์นี้เก็บลิงก์ไปยังทุกหน้าของเว็บไซต์เพื่อความสะดวกในการจัดทำดัชนีโดยเครื่องมือค้นหา (อันที่จริงการจัดทำดัชนีคือการแยกวิเคราะห์เว็บไซต์โดย Yandex และ Google)

โดยทั่วไป เราไม่ควรสนใจมากว่าทำไมไฟล์นี้ถึงต้องการ สิ่งสำคัญคือถ้ามีอยู่ คุณไม่สามารถปีนหน้าเว็บไซต์ด้วยวิธีการที่ยุ่งยากใดๆ ได้ แต่เพียงแค่ใช้ไฟล์นี้

วิธีตรวจสอบการมีอยู่ของไฟล์นี้: แยกวิเคราะห์เว็บไซต์ site.ru จากนั้นอ้างอิงถึง site.ru/sitemap.xml ในเบราว์เซอร์ - หากคุณเห็นบางสิ่ง แสดงว่าไฟล์นั้นอยู่ที่นั่น และหากคุณไม่เห็น อนิจจา

หากมีแผนผังเว็บไซต์ แสดงว่ามีลิงก์ไปยังหน้าทั้งหมดของเว็บไซต์ในรูปแบบ XML อย่าลังเลที่จะใช้ XML นี้ แยกวิเคราะห์ แยกลิงก์ไปยังหน้าที่คุณต้องการในทางที่สะดวกสำหรับคุณ (เช่น โดยการแยกวิเคราะห์ URL ที่อธิบายไว้ในวิธีสไปเดอร์)

ด้วยเหตุนี้ คุณจะได้รับรายการลิงก์สำหรับการแยกวิเคราะห์ เหลือเพียงไปที่ลิงก์เหล่านั้นและแยกวิเคราะห์เนื้อหาที่คุณต้องการ

อ่านเพิ่มเติมเกี่ยวกับอุปกรณ์ sitemap.xml ในวิกิพีเดีย

คุณจะทำอย่างไรต่อไป:

เริ่มแก้ปัญหาได้ที่ลิงค์ต่อไปนี้ งานสำหรับบทเรียน

เมื่อตัดสินใจทุกอย่างแล้ว - ไปศึกษาหัวข้อใหม่


อนุญาตให้เผยแพร่บทความนี้โดยมีลิงก์ไปยังเว็บไซต์ของผู้เขียนบทความเท่านั้น

ในบทความนี้ ผมจะแสดงตัวอย่างวิธีแยกวิเคราะห์ไฟล์ XML ขนาดใหญ่ หากเซิร์ฟเวอร์ของคุณ (โฮสติ้ง) ไม่ได้ถูกห้ามไม่ให้เพิ่มเวลาทำงานของสคริปต์ คุณสามารถแยกวิเคราะห์ไฟล์ XML ที่มีน้ำหนักอย่างน้อยกิกะไบต์ โดยส่วนตัวแล้วฉันแยกวิเคราะห์เฉพาะไฟล์จากโอโซนที่มีน้ำหนัก 450 เมกะไบต์

มีปัญหาสองประการเมื่อแยกวิเคราะห์ไฟล์ XML ขนาดใหญ่:
1. หน่วยความจำไม่เพียงพอ
2. มีเวลาจัดสรรไม่เพียงพอสำหรับสคริปต์ในการทำงาน

ปัญหาที่สองเกี่ยวกับเวลาสามารถแก้ไขได้หากเซิร์ฟเวอร์ไม่ได้ห้าม
แต่ปัญหาของหน่วยความจำนั้นแก้ไขได้ยาก แม้ว่าเรากำลังพูดถึงเซิร์ฟเวอร์ของคุณเอง การย้ายไฟล์ขนาด 500 เมกะไบต์นั้นไม่ใช่เรื่องง่าย และแม้แต่ในโฮสติ้งและบน VDS คุณก็ไม่สามารถเพิ่มหน่วยความจำได้

PHP มีตัวเลือกการประมวลผล XML ในตัวหลายตัว - SimpleXML, DOM, SAX
ตัวเลือกทั้งหมดนี้มีรายละเอียดอยู่ในบทความตัวอย่างมากมาย แต่ตัวอย่างทั้งหมดแสดงวิธีการทำงานกับเอกสาร XML ฉบับสมบูรณ์

นี่คือตัวอย่างหนึ่ง เราได้วัตถุจากไฟล์ XML

ตอนนี้คุณสามารถประมวลผลวัตถุนี้ แต่...
อย่างที่คุณเห็น ไฟล์ XML ทั้งหมดจะถูกอ่านในหน่วยความจำ จากนั้นทุกอย่างจะถูกแยกวิเคราะห์เป็นวัตถุ
นั่นคือ ข้อมูลทั้งหมดเข้าสู่หน่วยความจำ และหากหน่วยความจำที่จัดสรรไม่เพียงพอ สคริปต์จะหยุดทำงาน

ตัวเลือกนี้ไม่เหมาะสำหรับการประมวลผลไฟล์ขนาดใหญ่ คุณต้องอ่านไฟล์ทีละบรรทัดและประมวลผลข้อมูลนี้ตามลำดับ
ในเวลาเดียวกัน การตรวจสอบความถูกต้องก็ถูกดำเนินการเช่นกันในขณะที่ข้อมูลมีการประมวลผล ดังนั้นคุณจะต้องสามารถย้อนกลับได้ เช่น ลบฐานข้อมูลทั้งหมดที่ป้อนในกรณีของไฟล์ XML ที่ไม่ถูกต้อง หรือทำผ่านสองครั้ง ผ่านไฟล์ อ่านเพื่อความถูกต้องก่อน จากนั้นอ่านเพื่อประมวลผลข้อมูล

นี่คือตัวอย่างทางทฤษฎีของการแยกวิเคราะห์ไฟล์ XML ขนาดใหญ่
สคริปต์นี้อ่านอักขระหนึ่งตัวจากไฟล์ รวบรวมข้อมูลนี้ลงในบล็อก และส่งไปยังตัวแยกวิเคราะห์ XML
วิธีนี้ช่วยแก้ปัญหาหน่วยความจำได้อย่างสมบูรณ์และไม่ก่อให้เกิดการโหลด แต่จะทำให้ปัญหารุนแรงขึ้นเมื่อเวลาผ่านไป วิธีพยายามแก้ปัญหาเมื่อเวลาผ่านไปอ่านด้านล่าง

ฟังก์ชัน webi_xml($file)
{

########
### ฟังก์ชั่นการจัดการข้อมูล

{
พิมพ์ $data ;
}
############################################



{
พิมพ์ $name ;
print_r($attrs);
}


## ฟังก์ชั่นปิดแท็ก
ฟังก์ชั่น endElement ($parser , $name )
{
พิมพ์ $name ;
}
############################################

($xml_parser , "ข้อมูล" );

// เปิดไฟล์
$fp = fopen($file , "r" );

$perviy_vxod = 1 ; $data = "" ;



{

$simvol = fgetc($fp); $data .= $simvol ;


if($simvol != ">" ) ( ทำต่อ;)


เสียงสะท้อน "

หยุดพัก;
}

$data = "" ;
}
fclose($fp);

webi_xml("1.xml");

?>

ในตัวอย่างนี้ ฉันใส่ทุกอย่างลงในฟังก์ชัน webi_xml () เดียว และการเรียกของฟังก์ชันนี้จะมองเห็นได้ที่ด้านล่างสุด
ตัวสคริปต์เองประกอบด้วยสามหน้าที่หลัก:
1. ฟังก์ชั่นที่จับการเปิดแท็ก startElement()
2. ฟังก์ชั่นที่จับการปิดของ endElement() tag
3. และฟังก์ชั่นการรับข้อมูล data()

สมมติว่าเนื้อหาของไฟล์ 1.xml เป็นสูตรบางอย่าง



< title >ขนมปังง่ายๆ
< ingredient amount = "3" unit = "стакан" >แป้ง
< ingredient amount = "0.25" unit = "грамм" >ยีสต์
< ingredient amount = "1.5" unit = "стакан" >น้ำอุ่น
< ingredient amount = "1" unit = "чайная ложка" >เกลือ
< instructions >
< step > ผสมส่วนผสมทั้งหมดแล้วนวดให้ละเอียด.
< step > คลุมด้วยผ้าแล้วทิ้งไว้ในห้องอุ่นเป็นเวลาหนึ่งชั่วโมง.
< step > นวดอีกครั้ง, วางถาดอบแล้วเข้าเตาอบ.
< step > เยี่ยมชมเว็บไซต์


เราเริ่มต้นด้วยการเรียกใช้ฟังก์ชันทั่วไป webi_xml("1.xml");
นอกจากนี้ ในฟังก์ชันนี้ parser จะเริ่มทำงานและชื่อแท็กทั้งหมดจะถูกแปลงเป็นตัวพิมพ์ใหญ่เพื่อให้แท็กทั้งหมดมีตัวพิมพ์เดียวกัน

$xml_parser = xml_parser_create();
xml_parser_set_option ($xml_parser , XML_OPTION_CASE_FOLDING , จริง );

ตอนนี้เราระบุฟังก์ชันที่จะตรวจจับการเปิดแท็ก ปิด และประมวลผลข้อมูล

xml_set_element_handler($xml_parser , "startElement" , "endElement" );
xml_set_character_data_handler($xml_parser , "ข้อมูล" );

ถัดมาเป็นการเปิดไฟล์ที่ระบุ วนซ้ำบนไฟล์ทีละหนึ่งอักขระและเพิ่มอักขระแต่ละตัวลงในตัวแปรสตริงจนกว่าจะพบอักขระ > .
หากนี่คือการเข้าถึงไฟล์ครั้งแรก ทุกอย่างที่ไม่จำเป็นในตอนต้นของไฟล์จะถูกลบไปตลอดทาง ทุกสิ่งที่อยู่ก่อนหน้านั้น นี่คือแท็ก XML ควรเริ่มต้นด้วย
ครั้งแรกที่ตัวแปรสตริงจะรวบรวมสตริง

แล้วส่งไปที่ parser
xml_parse ($xml_parser , $data , feof ($fp ));
หลังจากประมวลผลข้อมูลแล้ว ตัวแปรสตริงจะถูกรีเซ็ต และการรวบรวมข้อมูลในสตริงจะเริ่มต้นอีกครั้งและสตริงจะถูกสร้างขึ้นเป็นครั้งที่สอง

ในครั้งที่สาม
</b><br>ในที่สี่ <br><b>ขนมปังง่ายๆ

โปรดทราบว่าตัวแปรสตริงจะถูกสร้างขึ้นโดย tag ที่สมบูรณ์เสมอ > และไม่จำเป็นต้องส่งแท็กเปิดและปิดพร้อมข้อมูลไปยังตัวแยกส่วน ตัวอย่างเช่น
ขนมปังง่ายๆ
มันเป็นสิ่งสำคัญสำหรับตัวจัดการนี้ที่จะได้รับแท็กที่ไม่เสียหายทั้งหมดอย่างน้อยหนึ่งแท็กที่เปิดอยู่และในขั้นตอนต่อไปแท็กปิดหรือได้รับไฟล์ 1,000 บรรทัดทันทีไม่สำคัญ สิ่งสำคัญคือแท็ก ไม่แตกหัก ตัวอย่างเช่น

le>ขนมปังง่ายๆ
ดังนั้นจึงเป็นไปไม่ได้ที่จะส่งข้อมูลไปยังตัวจัดการ เนื่องจากแท็กเสีย
คุณสามารถคิดวิธีการส่งข้อมูลไปยังตัวจัดการของคุณเองได้ เช่น รวบรวมข้อมูล 1 เมกะไบต์แล้วส่งไปยังตัวจัดการเพื่อเพิ่มความเร็ว เพียงตรวจสอบให้แน่ใจว่าแท็กสิ้นสุดเสมอและข้อมูลอาจเสียหายได้
เรียบง่าย</b><br><b>ขนมปัง

ดังนั้นคุณสามารถส่งไฟล์ขนาดใหญ่ไปยังตัวจัดการได้ในส่วนต่าง ๆ ตามที่คุณต้องการ

ตอนนี้เรามาดูกันว่าข้อมูลนี้ได้รับการประมวลผลอย่างไรและจะได้รับอย่างไร

เริ่มด้วยฟีเจอร์แท็กเปิด startElement ($parser , $name , $attrs )
สมมติว่าการประมวลผลมาถึงเส้นแล้ว
< ingredient amount = "3" unit = "стакан" >แป้ง
จากนั้นภายในฟังก์ชันตัวแปร $name จะเท่ากับ วัตถุดิบนั่นคือชื่อของแท็กเปิด (เรื่องยังไม่ถึงการปิดแท็ก)
นอกจากนี้ ในกรณีนี้ จะมีอาร์เรย์แอตทริบิวต์ของแท็ก $attrs ซึ่งจะมี data จำนวน = "3" และหน่วย = "แก้ว".

หลังจากนั้น ข้อมูลของแท็กเปิดจะถูกประมวลผลโดยฟังก์ชัน ข้อมูล ($ parser , $data )
ตัวแปร $data จะมีทุกอย่างที่อยู่ระหว่างแท็กเปิดและแท็กปิด ในกรณีของเราคือข้อความ Muk

และการประมวลผลสตริงของเราโดยฟังก์ชันก็เสร็จสิ้น endElement ($parser , $name )
นี่คือชื่อแท็กปิด ในกรณีของเรา $name จะเท่ากับ วัตถุดิบ

และหลังจากนั้น ทุกอย่างก็กลับมาเต็มวงอีกครั้ง

ตัวอย่างข้างต้นแสดงให้เห็นถึงหลักการของการประมวลผล XML เท่านั้น แต่สำหรับแอปพลิเคชันจริงจำเป็นต้องได้รับการสรุป
โดยปกติ คุณต้องแยกวิเคราะห์ XML ขนาดใหญ่เพื่อป้อนข้อมูลลงในฐานข้อมูล และสำหรับการประมวลผลข้อมูลที่เหมาะสม คุณต้องรู้ว่าข้อมูลนั้นเป็นของแท็กที่เปิดอยู่ ระดับของการซ้อนแท็ก และแท็กใดที่เปิดอยู่ในลำดับชั้นด้านบน ด้วยข้อมูลนี้ คุณสามารถประมวลผลไฟล์ได้อย่างถูกต้องโดยไม่มีปัญหาใดๆ
ในการทำเช่นนี้ คุณต้องแนะนำตัวแปรส่วนกลางหลายตัวที่จะรวบรวมข้อมูลเกี่ยวกับแท็กที่เปิด การซ้อน และข้อมูล
นี่คือตัวอย่างที่สามารถใช้ได้

ฟังก์ชัน webi_xml($file)
{
โกลบอล $webi_depth ; // ตัวนับเพื่อติดตามความลึกของรัง
$webi_depth = 0 ;
โกลบอล $webi_tag_open ; // จะมีอาร์เรย์ของแท็กที่เปิดอยู่ในปัจจุบัน
$webi_tag_open = array();
โกลบอล $webi_data_temp ; // อาร์เรย์นี้จะมีข้อมูลของหนึ่งแท็ก

####################################################
### ฟังก์ชั่นการจัดการข้อมูล
ข้อมูลฟังก์ชัน ($parser , $data )
{
โกลบอล $webi_depth ;
โกลบอล $webi_tag_open ;
โกลบอล $webi_data_temp ;
// เพิ่มข้อมูลลงในอาร์เรย์ด้วยการซ้อนและแท็กที่เปิดอยู่ในปัจจุบัน
$webi_data_temp [ $webi_depth ][ $webi_tag_open [ $webi_depth ]][ "data" ].= $data ;
}
############################################

####################################################
### ฟังก์ชั่นแท็กเปิด
ฟังก์ชัน startElement ($parser , $name , $attrs )
{
โกลบอล $webi_depth ;
โกลบอล $webi_tag_open ;
โกลบอล $webi_data_temp ;

// หากระดับการซ้อนไม่เป็นศูนย์ แสดงว่ามีหนึ่งแท็กเปิดอยู่แล้ว
// และข้อมูลจากมันอยู่ในอาร์เรย์แล้ว คุณสามารถประมวลผลได้
ถ้า ($webi_depth)
{




" ;

พิมพ์"
" ;
print_r($webi_tag_open); // อาร์เรย์ของแท็กที่เปิดอยู่
พิมพ์"


" ;

// หลังจากประมวลผลข้อมูลแล้ว ให้ลบออกเพื่อเพิ่มหน่วยความจำ
unset($GLOBALS [ "webi_data_temp" ][ $webi_depth ]);
}

// ตอนนี้การเปิดแท็กถัดไปได้เริ่มขึ้นแล้ว และการประมวลผลต่อไปจะเกิดขึ้นในขั้นตอนต่อไป
$webi_deep++; // เพิ่มการทำรัง

$webi_tag_open [ $webi_depth ]= $name ; // เพิ่มแท็กเปิดให้กับอาร์เรย์ข้อมูล
$webi_data_temp [ $webi_depth ][ $name ][ "attrs" ]= $attrs ; // ตอนนี้เพิ่มแอตทริบิวต์แท็ก

}
###############################################

#################################################
## ฟังก์ชั่นปิดแท็ก
ฟังก์ชั่น endElement ($parser , $name ) (
โกลบอล $webi_depth ;
โกลบอล $webi_tag_open ;
โกลบอล $webi_data_temp ;

// การประมวลผลข้อมูลเริ่มต้นที่นี่ เช่น การเพิ่มลงในฐานข้อมูล การบันทึกลงในไฟล์ เป็นต้น
// $webi_tag_open มีห่วงโซ่ของแท็กเปิดโดยระดับการซ้อน
// ตัวอย่างเช่น $webi_tag_open[$webi_depth] มีชื่อของแท็กเปิดที่กำลังประมวลผลข้อมูลอยู่
// ระดับการซ้อนแท็ก $webi_depth
// $webi_data_temp[$webi_depth][$webi_tag_open[$webi_depth]]["attrs"] อาร์เรย์ของแอตทริบิวต์แท็ก
// $webi_data_temp[$webi_depth][$webi_tag_open[$webi_depth]]["data"] ข้อมูลแท็ก

พิมพ์ "ข้อมูล" $webi_tag_open [ $webi_depth ] "--" .($webi_data_temp [ $webi_depth ][ $webi_tag_open [ $webi_depth ]][ "data" ]) "
" ;
print_r ($webi_data_temp [ $webi_depth ][ $webi_tag_open [ $webi_depth ]][ "attrs" ]);
พิมพ์"
" ;
print_r($webi_tag_open);
พิมพ์"


" ;

Unset($GLOBALS [ "webi_data_temp" ]); // หลังจากประมวลผลข้อมูลแล้ว ให้ลบอาร์เรย์ที่มีข้อมูลทั้งหมด เนื่องจากแท็กถูกปิด
unset($GLOBALS [ "webi_tag_open" ][ $webi_depth ]); // ลบข้อมูลเกี่ยวกับแท็กที่เปิดนี้... เนื่องจากปิดแล้ว

$webi_depth --; // ลดการทำรัง
}
############################################

$xml_parser = xml_parser_create();
xml_parser_set_option ($xml_parser , XML_OPTION_CASE_FOLDING , จริง );

// ระบุฟังก์ชันที่จะทำงานเมื่อเปิดและปิดแท็ก
xml_set_element_handler($xml_parser , "startElement" , "endElement" );

// ระบุฟังก์ชันสำหรับการทำงานกับ data
xml_set_character_data_handler($xml_parser , "ข้อมูล" );

// เปิดไฟล์
$fp = fopen($file , "r" );

$perviy_vxod = 1 ; // แฟล็กสำหรับตรวจสอบอินพุตแรกไปยังไฟล์
$data = "" ; // ที่นี่เรารวบรวมบางส่วนของข้อมูลจากไฟล์และส่งไปยัง parser xml

// วนซ้ำจนถึงจุดสิ้นสุดของไฟล์ที่พบ
ในขณะที่ (! feof ($fp ) และ $fp )
{
$simvol = fgetc($fp); // อ่านอักขระหนึ่งตัวจากไฟล์
$data .= $simvol ; // เพิ่มอักขระนี้ในข้อมูลที่จะส่ง

// หากอักขระไม่ใช่แท็กปิดท้าย ให้กลับไปที่จุดเริ่มต้นของลูปและเพิ่มอักขระอีกหนึ่งตัวในข้อมูล เป็นต้น จนกว่าจะพบแท็กสิ้นสุด
if($simvol != ">" ) ( ทำต่อ;)
// หากพบแท็กปิด ให้ส่งข้อมูลที่รวบรวมนี้ไปยังการประมวลผล

// ตรวจสอบว่าเป็นรายการแรกในไฟล์หรือไม่ จากนั้นให้ลบทุกอย่างที่อยู่หน้าแท็ก// เนื่องจากบางครั้งอาจมีขยะก่อนที่จะเริ่ม XML (ตัวแก้ไขเงอะงะหรือสคริปต์ได้รับไฟล์จากเซิร์ฟเวอร์อื่น)
if($perviy_vxod ) ( $data = strstr ($data , "

// ตอนนี้เราส่งข้อมูลไปยัง parser xml
ถ้า (! xml_parse ($xml_parser , $data , feof ($fp ))) (

// ที่นี่คุณสามารถประมวลผลและรับข้อผิดพลาดเพื่อความถูกต้อง...
// ทันทีที่พบข้อผิดพลาด การแยกวิเคราะห์จะหยุด
เสียงสะท้อน "
ข้อผิดพลาด XML: " .xml_error_string (xml_get_error_code ($xml_parser ));
echo "ที่บรรทัด" xml_get_current_line_number($xml_parser );
หยุดพัก;
}

// หลังจากแยกวิเคราะห์ เราจะทิ้งข้อมูลที่รวบรวมไว้สำหรับขั้นตอนต่อไปของลูป
$data = "" ;
}
fclose($fp);
xml_parser_free($xml_parser );
// ลบตัวแปรโกลบอล
unset($GLOBALS [ "webi_depth" ]);
unset($GLOBALS [ "webi_tag_open" ]);
unset($GLOBALS [ "webi_data_temp" ]);

webi_xml("1.xml");

?>

ตัวอย่างทั้งหมดมาพร้อมกับความคิดเห็น ตอนนี้ทดสอบและทดลอง
โปรดทราบว่าในฟังก์ชันการจัดการข้อมูล ข้อมูลไม่ได้ถูกแทรกลงในอาร์เรย์เพียงอย่างเดียว แต่ถูกเพิ่มโดยใช้ " .=" เนื่องจากข้อมูลอาจไม่ได้มาทั้งรูปแบบ และหากคุณเพิ่งมอบหมายงาน คุณจะได้รับข้อมูลเป็นส่วนๆ ในบางครั้ง

เท่านี้ก็เรียบร้อย ตอนนี้จะมีหน่วยความจำเพียงพอในการประมวลผลไฟล์ทุกขนาด แต่เวลาทำงานของสคริปต์สามารถเพิ่มขึ้นได้หลายวิธี
แทรกฟังก์ชันที่จุดเริ่มต้นของสคริปต์
set_time_limit(6000);
หรือ
ini_set("max_execution_time" , "6000" );

หรือเพิ่มข้อความในไฟล์ .htaccess
php_value max_execution_time 6000

ตัวอย่างเหล่านี้จะเพิ่มเวลาทำงานของสคริปต์เป็น 6000 วินาที
คุณสามารถเพิ่มเวลาด้วยวิธีนี้ได้เฉพาะในเซฟโหมดปิด

หากคุณมีสิทธิ์เข้าถึงเพื่อแก้ไข php.ini คุณสามารถเพิ่มเวลาด้วย
max_execution_time = 6000

ตัวอย่างเช่น บนมาสเตอร์โฮสต์โฮสติ้ง ในขณะที่เขียนนี้ การเพิ่มเวลาสคริปต์เป็นสิ่งต้องห้าม แม้จะปิดใช้งานเซฟโหมด แต่หากคุณเป็นมือโปร คุณสามารถสร้าง php ของคุณบนมาสเตอร์โฮสต์ได้ แต่นี่ไม่ใช่ในบทความนี้ .

ตัวอย่างบางส่วนในคู่มือนี้รวมถึงสตริง XML แทนที่จะทำซ้ำในทุกตัวอย่าง ให้ใส่บรรทัดนี้ในไฟล์และรวมไว้ในทุกตัวอย่าง บรรทัดนี้แสดงในตัวอย่างต่อไปนี้ นอกจากนี้ คุณสามารถสร้างเอกสาร XML และอ่านด้วยฟังก์ชัน simplexml_load_file().

ตัวอย่าง #1 ไฟล์ Example.php พร้อมสตริง XML

$xmlstr =<<


PHP: Parser ปรากฏขึ้น


นางสาว. นักเขียนโค้ด
Onlivia Actora


นาย. นักเขียนโค้ด
El ActÓr


ดังนั้นจึงเป็นภาษา ยังคงเป็นภาษาโปรแกรม หรือ
มันเป็นภาษาสคริปต์หรือไม่? เปิดเผยหมดแล้วในสารคดีเรื่องนี้
คล้ายกับหนังสยองขวัญ




7
5


XML
?>

SimpleXML ใช้งานง่ายมาก! ลองรับสตริงหรือตัวเลขจากเอกสาร XML ที่เกี่ยวข้อง

ตัวอย่าง #2 รับส่วนหนึ่งของเอกสาร

รวม "example.php" ;

echo $movies -> ภาพยนตร์ [ 0 ] -> พล็อต ;
?>

ดังนั้นจึงเป็นภาษา ยังคงเป็นภาษาโปรแกรม หรือเป็นภาษาสคริปต์? ทุกอย่างถูกเปิดเผยในสารคดีที่ดูเหมือนหนังสยองขวัญเรื่องนี้

ใน PHP คุณสามารถเข้าถึงองค์ประกอบในเอกสาร XML ที่มีอักขระที่ไม่ถูกต้อง (เช่น ยัติภังค์) ในชื่อได้โดยการใส่ชื่อองค์ประกอบที่ระบุในวงเล็บปีกกาและเครื่องหมายอะพอสทรอฟี

ตัวอย่าง #3 รับสตริง

รวม "example.php" ;

echo $movies -> movie ->( "great-lines" )-> line ;
?>

ผลลัพธ์ของการรันตัวอย่างนี้:

PHP แก้ปัญหาทั้งหมดของฉันบนเว็บ

ตัวอย่าง #4 การเข้าถึงองค์ประกอบที่ไม่ซ้ำใน SimpleXML

ในกรณีที่มีองค์ประกอบย่อยหลายอินสแตนซ์ในองค์ประกอบหลักเดียวกัน จะต้องใช้วิธีวนซ้ำมาตรฐาน

รวม "example.php" ;

$movies = ใหม่ SimpleXMLElement($xmlstr );

/* สำหรับแต่ละโหนด , เราจะส่งออกชื่อแยกกัน . */
foreach ($movies -> movie -> character -> character เป็น $character ) (
echo $character -> name , "เล่น" , $character -> นักแสดง , PHP_EOL ;
}

?>

ผลลัพธ์ของการรันตัวอย่างนี้:

นางสาว. Coder รับบทเป็น Onlivia Actora Mr. Coder เล่น El ActÓr

ความคิดเห็น:

คุณสมบัติ ( $movies->moviesในตัวอย่างก่อนหน้านี้) ไม่ใช่อาร์เรย์ เป็นวัตถุ iterable ในรูปแบบของอาร์เรย์

ตัวอย่าง #5 การใช้แอตทริบิวต์

จนถึงตอนนี้ เราได้รับเพียงชื่อและค่าขององค์ประกอบเท่านั้น SimpleXML ยังสามารถเข้าถึงแอตทริบิวต์ขององค์ประกอบ แอตทริบิวต์องค์ประกอบสามารถเข้าถึงได้ในลักษณะเดียวกับองค์ประกอบอาร์เรย์ ( อาร์เรย์).

รวม "example.php" ;

$movies = ใหม่ SimpleXMLElement($xmlstr );

/* เข้าถึงโหนด หนังเรื่องแรก
* เราจะแสดงมาตราส่วนการให้คะแนนด้วย */
foreach ($movies -> หนัง [ 0 ]-> ให้คะแนนเป็น $rating ) (
สวิตช์ ((สตริง) คะแนน $ [ "ประเภท" ]) ( // รับแอตทริบิวต์องค์ประกอบโดย index
กรณี "นิ้วโป้ง" :
echo $rating , " ยกนิ้วให้ " ;
หยุดพัก;
กรณี "ดาว" :
echo $rating , "ดาว" ;
หยุดพัก;
}
}
?>

ผลลัพธ์ของการรันตัวอย่างนี้:

7 ยกนิ้วให้5ดาว

ตัวอย่าง #6 การเปรียบเทียบองค์ประกอบและคุณลักษณะกับข้อความ

หากต้องการเปรียบเทียบองค์ประกอบหรือแอตทริบิวต์กับสตริง หรือส่งผ่านไปยังฟังก์ชันเป็นข้อความ คุณต้องแปลงเป็นสตริงโดยใช้ (สตริง). มิฉะนั้น PHP จะถือว่าองค์ประกอบนั้นเป็นวัตถุ

รวม "example.php" ;

$movies = ใหม่ SimpleXMLElement($xmlstr );

ถ้า ((สตริง) $movies -> movie -> title == "PHP: Parser ปรากฏขึ้น") {
พิมพ์ "ภาพยนตร์เรื่องโปรดของฉัน";
}

echo htmlentities ((สตริง) $movies -> movie -> title );
?>

ผลลัพธ์ของการรันตัวอย่างนี้:

หนังโปรดของฉัน PHP: The Parser Appears

ตัวอย่าง #7 การเปรียบเทียบสององค์ประกอบ

SimpleXMLElements สองรายการถือว่าแตกต่างกัน แม้ว่าจะชี้ไปที่อ็อบเจ็กต์เดียวกันกับ PHP 5.2.0

รวม "example.php" ;

$movies1 = ใหม่ SimpleXMLElement($xmlstr );
$movies2 = ใหม่ SimpleXMLElement($xmlstr );
var_dump ($movies1 == $movies2 ); // เท็จตั้งแต่ PHP 5.2.0
?>

ผลลัพธ์ของการรันตัวอย่างนี้:

Beispiel #8 ใช้ XPath

SimpleXML รวมการสนับสนุน XPath ดั้งเดิม ค้นหารายการทั้งหมด :

รวม "example.php" ;

$movies = ใหม่ SimpleXMLElement($xmlstr );

foreach ($movies -> xpath("//character" ) เป็น $character ) (
echo $character -> name , "เล่น" , $character -> นักแสดง , PHP_EOL ;
}
?>

"// " ทำหน้าที่เป็นไวด์การ์ด หากต้องการระบุพาธแบบสัมบูรณ์ ให้ข้ามเครื่องหมายสแลชตัวใดตัวหนึ่ง

ผลลัพธ์ของการรันตัวอย่างนี้:

นางสาว. Coder รับบทเป็น Onlivia Actora Mr. Coder เล่นโดย El ActÓr

ตัวอย่าง #9 การตั้งค่าค่า

ข้อมูลใน SimpleXML ไม่จำเป็นต้องเปลี่ยนแปลงได้ วัตถุช่วยให้คุณสามารถจัดการองค์ประกอบทั้งหมดได้

รวม "example.php" ;
$movies = ใหม่ SimpleXMLElement($xmlstr );

$movies -> ภาพยนตร์ [ 0 ]-> อักขระ -> อักขระ [ 0 ]-> name = "Miss Coder" ;

เสียงสะท้อน $movies -> asXML();
?>

ผลลัพธ์ของการรันตัวอย่างนี้:

PHP: Parser ปรากฏขึ้น Miss Coder Onlivia Actora นาย. นักเขียนโค้ด El ActÓr 7 5

ตัวอย่าง #10 การเพิ่มองค์ประกอบและคุณลักษณะ

ใน PHP 5.1.3, SimpleXML มีความสามารถในการเพิ่มองค์ประกอบลูกและแอตทริบิวต์ได้อย่างง่ายดาย

รวม "example.php" ;
$movies = ใหม่ SimpleXMLElement($xmlstr );

$character = $movies -> ภาพยนตร์ [ 0 ]-> ตัวอักษร -> addChild("character" );
$character -> addChild("name" , "Mr. Parser" );
$character -> addChild("นักแสดง" , "John Doe" );

$rating = $movies -> หนัง [ 0 ] -> addChild("เรตติ้ง" , "PG" );
คะแนน $ -> addAttribute ("ประเภท" , "mpaa" );

เสียงสะท้อน $movies -> asXML();
?>

ผลลัพธ์ของการรันตัวอย่างนี้:

PHP: Parser ปรากฏขึ้น นางสาว. นักเขียนโค้ด Onlivia Actora นาย. นักเขียนโค้ด El ActÓr นาย. พาร์เซอร์จอห์น โด ดังนั้นจึงเป็นภาษา ยังคงเป็นภาษาโปรแกรม หรือเป็นภาษาสคริปต์? ทุกอย่างถูกเปิดเผยในสารคดีที่ดูเหมือนหนังสยองขวัญเรื่องนี้ PHP แก้ปัญหาทั้งหมดของฉันบนเว็บ 7 5 PG

Beispiel #11 โต้ตอบกับDOM

PHP สามารถแปลงโหนด XML จาก SimpleXML เป็นรูปแบบ DOM และในทางกลับกัน ตัวอย่างนี้แสดงวิธีการแก้ไของค์ประกอบ DOM ใน SimpleXML

$dom = DOMDocument ใหม่ ;
$dom -> loadXML( "เรื่องไร้สาระ" );
ถ้า (! $dom ) (
เสียงก้อง "เกิดข้อผิดพลาดในการแยกวิเคราะห์เอกสาร";
ทางออก;
}

$books = simplexml_import_dom($dom );

echo $books -> book [ 0 ]-> title ;
?>

ผลลัพธ์ของการรันตัวอย่างนี้:

4 ปีที่แล้ว

มี "เคล็ดลับ" ทั่วไปที่มักเสนอให้แปลงวัตถุ SimpleXML เป็นอาร์เรย์ โดยเรียกใช้ผ่าน json_encode() และ json_decode() ฉันต้องการอธิบายว่าเหตุใดจึงเป็นความคิดที่ไม่ดี

อย่างง่ายที่สุด เนื่องจากจุดรวมของ SimpleXML คือใช้งานง่ายกว่าและมีประสิทธิภาพมากกว่าอาร์เรย์ธรรมดา ตัวอย่างเช่น คุณสามารถเขียนbar -> baz [ "bing" ] ?> และมีความหมายเดียวกับbar [ 0 ]-> baz [ 0 ][ "bing" ] ?> ไม่ว่าจะมีองค์ประกอบ bar หรือ baz กี่ตัวใน XML และถ้าคุณเขียนbar [ 0 ]-> baz [ 0 ] ?> คุณได้รับเนื้อหาสตริงทั้งหมดของโหนดนั้น - รวมถึงส่วน CDATA - ไม่ว่าจะมีองค์ประกอบย่อยหรือแอตทริบิวต์หรือไม่ คุณยังมีสิทธิ์เข้าถึงข้อมูลเนมสเปซ ความสามารถในการแก้ไข XML อย่างง่าย และแม้กระทั่งความสามารถในการ "นำเข้า" ลงในวัตถุ DOM เพื่อการจัดการที่มีประสิทธิภาพยิ่งขึ้น ทั้งหมดนี้หายไปโดยการเปลี่ยนวัตถุให้เป็นอาร์เรย์แทนที่จะอ่านเพื่อทำความเข้าใจตัวอย่างในหน้านี้

นอกจากนี้ เนื่องจากไม่ได้ออกแบบมาเพื่อจุดประสงค์นี้ การแปลงเป็น JSON และย้อนกลับจะสูญเสียข้อมูลจริงในบางสถานการณ์ ตัวอย่างเช่น องค์ประกอบหรือแอตทริบิวต์ใดๆ ในเนมสเปซจะถูกละทิ้ง และเนื้อหาข้อความใดๆ จะถูกละทิ้งหากองค์ประกอบมีลูกหรือแอตทริบิวต์ด้วย บางครั้งสิ่งนี้ไม่สำคัญ แต่ถ้าคุณคุ้นเคยกับการแปลงทุกอย่างเป็นอาร์เรย์ มันจะต่อยคุณในที่สุด

แน่นอน คุณสามารถเขียนการแปลงที่ชาญฉลาดกว่า ซึ่งไม่มีข้อจำกัดเหล่านี้ แต่ ณ จุดนั้น คุณจะไม่ได้รับค่าจาก SimpleXML เลย และควรใช้ฟังก์ชัน XML Parser ระดับล่าง หรือคลาส XMLReader เพื่อสร้างโครงสร้างของคุณ คุณจะยังไม่มีฟังก์ชันอำนวยความสะดวกพิเศษของ SimpleXML แต่นั่นคือการสูญเสียของคุณ

2 ปีที่แล้ว

หากสตริง xml ของคุณมีบูลีนที่เข้ารหัสด้วย "0" และ "1" คุณจะประสบปัญหาเมื่อคุณส่งองค์ประกอบไปยังบูลโดยตรง:

$xmlstr =<<

1
0

XML
$values ​​​​= ใหม่ SimpleXMLElement($xmlstr);
$truevalue = (บูล)$values->truevalue; // จริง
$falsevalue = (บูล)$values->falsevalue; //จริงด้วย!!!

แทนที่จะต้อง cast to string หรือ int ก่อน:

$truevalue = (บูล)(int)$values->truevalue; // จริง
$falsevalue = (บูล)(int)$values->falsevalue; // เท็จ

9 ปีที่แล้ว

หากคุณต้องการเอาต์พุต xml ที่ถูกต้องในการตอบกลับ อย่าลืมตั้งค่าประเภทเนื้อหาส่วนหัวเป็น xml นอกเหนือจากการสะท้อนผลลัพธ์ของ asXML():

$xml = simplexml_load_file("...");
...
... xml สิ่ง
...

// เอาต์พุต xml ในการตอบกลับของคุณ:
ส่วนหัว ("ประเภทเนื้อหา: ข้อความ/xml");
เสียงสะท้อน $xml -> asXML();
?>

9 ปีที่แล้ว

จากไฟล์ README:

SimpleXML เป็นวิธีที่ง่ายในการเข้าถึงข้อมูล XML

ออบเจ็กต์ SimpleXML เป็นไปตามกฎพื้นฐานสี่ข้อ:

1) คุณสมบัติแสดงถึงองค์ประกอบ iterators
2) ดัชนีตัวเลขแสดงถึงองค์ประกอบ
3) ดัชนีที่ไม่ใช่ตัวเลขแสดงถึงคุณลักษณะ
4) การแปลงสตริงช่วยให้เข้าถึงข้อมูล TEXT ได้

เมื่อวนซ้ำคุณสมบัติ ส่วนขยายจะวนซ้ำเสมอ
โหนดทั้งหมดที่มีชื่อองค์ประกอบนั้น ดังนั้นเมธอด children() ต้องเป็น
เรียกเพื่อวนซ้ำโหนดย่อย แต่ยังทำสิ่งต่อไปนี้:
foreach ($obj->node_name เป็น $elem) (
// ทำอะไรบางอย่างกับ $elem
}
ส่งผลให้เกิดการวนซ้ำขององค์ประกอบ "node_name" อีกต่อไปแล้ว
จำเป็นต้องตรวจสอบเพื่อแยกแยะจำนวนโหนดประเภทนั้น

เมื่อมีการเข้าถึงข้อมูล TEXT องค์ประกอบผ่านคุณสมบัติ
ผลลัพธ์จะไม่รวมข้อมูล TEXT ขององค์ประกอบย่อย

ปัญหาที่ทราบ
============

เนื่องจากปัญหาเครื่องยนต์จึงไม่สามารถเข้าถึงได้ในขณะนี้
องค์ประกอบย่อยโดยดัชนี 0: $object->property

8 ปีที่แล้ว

ใช้สิ่งต่าง ๆ เช่น: is_object($xml->module->admin) เพื่อตรวจสอบว่ามีโหนดที่เรียกว่า "admin" จริงหรือไม่ ดูเหมือนจะไม่ทำงานตามที่คาดไว้ เนื่องจาก simplexml จะส่งคืนอ็อบเจ็กต์เสมอ - ในกรณีนี้จะเป็นอันว่าง - แม้ว่าจะไม่มีโหนดใดอยู่
สำหรับฉันฟังก์ชั่น empty() แบบเก่าที่ดีดูเหมือนว่าจะทำงานได้ดีในกรณีเช่นนี้

8 ปีที่แล้ว

เคล็ดลับด่วนเกี่ยวกับคิวรี xpath และเนมสเปซเริ่มต้น ดูเหมือนว่าระบบ XML ที่อยู่เบื้องหลัง SimpleXML จะมีการทำงานเหมือนกับที่ฉันเชื่อว่าระบบ XML .NET ใช้: เมื่อเราต้องการระบุบางสิ่งในเนมสเปซเริ่มต้น เราจะต้องประกาศเนมสเปซโดยใช้ registerXPathNamespace แล้วใช้คำนำหน้าเพื่อ ระบุอย่างอื่นในองค์ประกอบชีวิตเนมสเปซเริ่มต้น

$string =<<

สี่สิบอะไร?
โจ
เจน

ฉันรู้ว่านั่นคือคำตอบ แต่คำถามคืออะไร




XML

$xml = simplexml_load_string ($สตริง );
$xml -> registerXPathNamespace("def" , "http://www.w3.org/2005/Atom");

$nodes = $xml -> xpath("//def:document/def:title" );

?>

9 ปีที่แล้ว

ในขณะที่ SimpleXMLElement อ้างว่า iterable ดูเหมือนจะไม่ได้ใช้ฟังก์ชันอินเทอร์เฟซ Iterator มาตรฐาน เช่น::next และ::reset อย่างถูกต้อง ดังนั้นในขณะที่ foreach() ทำงาน ฟังก์ชันเช่น next(), current() หรือ each() ดูเหมือนจะไม่ทำงานตามที่คุณคาดไว้ ดูเหมือนว่าตัวชี้จะไม่เคลื่อนที่หรือถูกรีเซ็ตต่อไป

6 ปีที่แล้ว

หากการเข้ารหัสของเอกสาร XML ไม่ใช่ UTF-8 การประกาศการเข้ารหัสต้องมาต่อจาก version="..." และก่อน standalone="..." นี่เป็นข้อกำหนดของมาตรฐาน XML

หากการเข้ารหัสเอกสาร XML แตกต่างจาก UTF-8 การประกาศการเข้ารหัสควรทำตามหลังเวอร์ชัน = "..." และก่อนเวอร์ชันสแตนด์อโลน = "..." ข้อกำหนดนี้เป็น XML มาตรฐาน


ตกลง

ภาษารัสเซีย. ภาษาอังกฤษ


ข้อผิดพลาดร้ายแรง: Uncaught ข้อยกเว้น "ข้อยกเว้น" พร้อมข้อความ "สตริงไม่สามารถแยกวิเคราะห์เป็น XML" ใน...

XML ภาษามาร์กอัปที่ขยายได้คือชุดของกฎสำหรับการเข้ารหัสเอกสารในรูปแบบที่เครื่องอ่านได้ XML เป็นรูปแบบที่นิยมสำหรับการแลกเปลี่ยนข้อมูลบนอินเทอร์เน็ต ไซต์ที่อัปเดตเนื้อหาบ่อยครั้ง เช่น ไซต์ข่าวสารหรือบล็อก มักจะให้ฟีด XML เพื่อให้โปรแกรมภายนอกทราบถึงการเปลี่ยนแปลงของเนื้อหา การส่งและแยกวิเคราะห์ข้อมูล XML เป็นงานทั่วไปสำหรับแอปพลิเคชันที่มีการเชื่อมต่อเครือข่าย บทเรียนนี้อธิบายวิธีแยกวิเคราะห์เอกสาร XML และใช้ข้อมูล

การเลือก Parser

การวิเคราะห์ช่อง

ขั้นตอนแรกในการแยกวิเคราะห์ฟีดคือการตัดสินใจว่าเขตข้อมูลใดที่คุณสนใจ โปรแกรมแยกวิเคราะห์แยกฟิลด์ที่กำหนดและละเว้นทุกอย่างอื่น

นี่คือข้อมูลโค้ดช่องที่จะแยกวิเคราะห์ในแอปพลิเคชันตัวอย่าง แต่ละโพสต์บน StackOverflow.com จะปรากฏในฟีดเป็นแท็กรายการ ซึ่งมีแท็กที่ซ้อนกันหลายแท็ก:

คำถามใหม่ล่าสุดที่ติดแท็ก android - android - Program QA ... ... http://stackoverflow.com/q/9439999 0 ไฟล์ข้อมูลของฉันอยู่ที่ไหน หน้าผา2310 http://stackoverflow.com/users/1128925 2012-02-25T00:30:54Z 2012-02-25T00:30:54Z

ฉันมีแอปพลิเคชันที่ต้องใช้ไฟล์ข้อมูล...

... ...

แอปพลิเคชันตัวอย่างดึงข้อมูลจากแท็กรายการและชื่อแท็กย่อย ลิงก์ และสรุป

การสร้างอินสแตนซ์ของ Parser

ขั้นตอนต่อไปคือการสร้างอินสแตนซ์ parser และเริ่มกระบวนการแยกวิเคราะห์ ในตัวอย่างนี้ parser จะถูกเตรียมข้อมูลเบื้องต้นเพื่อไม่ให้จัดการเนมสเปซและยังใช้ InputStream ที่ให้มาเป็นอินพุต กระบวนการแยกวิเคราะห์เริ่มต้นด้วยการเรียกใช้ nextTag() และเรียกใช้เมธอด readFeed() ซึ่งจะดึงและประมวลผลข้อมูลที่แอปพลิเคชันสนใจ:

คลาสสาธารณะ StackOverflowXmlParser (// เราไม่ได้ใช้เนมสเปซส่วนตัวแบบคงที่สุดท้าย String ns = null รายการแยกวิเคราะห์สาธารณะ (InputStream ใน) ​​พ่น XmlPullParserException, IOException ( ลอง ( XmlPullParser parser = Xml.newPullParser (); parser.setFeature (XmlPullSPull_ParserC) , เท็จ); parser.setInput(ใน, null); parser.nextTag(); ส่งคืน readFeed(parser); ) ในที่สุด ( in.close(); ) ) ... )

ลบช่อง

เมธอด readFeed() ทำงานจริงในการประมวลผลฟีด องค์ประกอบที่มีแท็ก "รายการ" เป็นจุดเริ่มต้นสำหรับการประมวลผลช่องสัญญาณแบบเรียกซ้ำ หากแท็กถัดไปไม่ใช่แท็กรายการ จะถูกข้ามไป หลังจากที่ประมวลผล "ฟีด" ทั้งหมดซ้ำแล้วซ้ำอีก readFeed() จะส่งกลับรายการที่มีรายการ (รวมถึงรายการข้อมูลที่ซ้อนกัน) ที่ดึงมาจากฟีด รายการนี้จะถูกส่งคืนโดย parser

รายการส่วนตัว readFeed(XmlPullParser parser) พ่น XmlPullParserException, IOException ( รายการรายการ = ใหม่ ArrayList (); parser.require(XmlPullParser.START_TAG, ns, "feed"); ในขณะที่ (parser.next() != XmlPullParser.END_TAG) ( ถ้า (parser.getEventType() != XmlPullParser.START_TAG) ( ทำต่อ; ) ชื่อสตริง = parser.getName(); // เริ่มต้นด้วยการค้นหาแท็กรายการ if (name.equals("entry")) ( entries.add( readEntry(parser)); ) อื่น ๆ (ข้าม (parser); ) ) ส่งคืนรายการ; )

การแยกวิเคราะห์ XML

ขั้นตอนในการแยกวิเคราะห์ฟีด XML มีดังนี้:

ตัวอย่างนี้แสดงให้เห็นว่า parser แยกวิเคราะห์รายการ ชื่อเรื่อง ลิงก์ และข้อมูลสรุปอย่างไร

รายการคลาสคงที่สาธารณะ (ชื่อสตริงสุดท้ายสาธารณะ ลิงก์สตริงสุดท้ายสาธารณะ สรุปสตริงสุดท้ายสาธารณะ รายการส่วนตัว (ชื่อสตริง สรุปสตริง ลิงก์สตริง) ( this.title = ชื่อ; this.summary = สรุป; this.link = ลิงก์ ; ) ) // แยกวิเคราะห์เนื้อหาของรายการ หากพบชื่อ ข้อมูลสรุป หรือแท็กลิงก์ ให้ส่งต่อ // ให้กับวิธีการ "อ่าน" ที่เกี่ยวข้องเพื่อการประมวลผล มิฉะนั้นให้ข้ามแท็ก รายการส่วนตัว readEntry (XmlPullParser parser) พ่น XmlPullParserException, IOException ( parser.require(XmlPullParser.START_TAG, ns, "entry"); String title = null; String Summary = null; String link = null; while (parser.next() ! = XmlPullParser.END_TAG) ( if (parser.getEventType() != XmlPullParser.START_TAG) ( ทำต่อ; ) ชื่อสตริง = parser.getName(); if (name.equals("title")) ( title = readTitle(parser) ; ) else if (name.equals("summary")) ( summary = readSummary(parser); ) else if (name.equals("link")) ( link = readLink(parser); ) else (ข้าม (parser) ; ) ) ส่งคืนรายการใหม่ (ชื่อ, สรุป, ลิงก์); ) // ประมวลผลแท็กชื่อในฟีด สตริงส่วนตัว readTitle(XmlPullParser parser) พ่น IOException, XmlPullParserException ( parser.require(XmlPullParser.START_TAG, ns, "title"); String title = readText(parser); parser.require(XmlPullParser.END_TAG, ns, "title"); return title; ) // ประมวลผลแท็กลิงก์ในฟีด สตริงส่วนตัว readLink (XmlPullParser parser) พ่น IOException, XmlPullParserException ( String link = ""; parser.require(XmlPullParser.START_TAG, ns, "link"); String tag = parser.getName(); String relType = parser.getAttributeValue (null , "rel"); if (tag.equals("link")) ( if (relType.equals("alternate"))( link = parser.getAttributeValue(null, "href"); parser.nextTag(); ) ) parser.require(XmlPullParser.END_TAG, ns, "link"); return link; ) // ประมวลผลแท็กสรุปในฟีด สตริงส่วนตัว readSummary(XmlPullParser parser) พ่น IOException, XmlPullParserException ( parser.require(XmlPullParser.START_TAG, ns, "summary"); String Summary = readText(parser); parser.require(XmlPullParser.END_TAG, ns); "summary ส่งคืนสรุป ) // สำหรับชื่อแท็กและสรุป แยกค่าข้อความ สตริงส่วนตัว readText (XmlPullParser parser) พ่น IOException, XmlPullParserException ( String result = ""; if (parser.next() == XmlPullParser.TEXT) ( result = parser.getText(); parser.nextTag(); ) ส่งกลับผลลัพธ์; ) ... )

ข้ามรายการที่คุณไม่ต้องการ

ในหนึ่งในขั้นตอนการแยกวิเคราะห์ XML ที่อธิบายข้างต้น parser จะข้ามแท็กที่เราไม่สนใจ ด้านล่างนี้คือรหัส parser สำหรับวิธี skip():

การข้ามโมฆะส่วนตัว (ตัวแยกวิเคราะห์ XmlPullParser) พ่น XmlPullParserException, IOException ( if (parser.getEventType() != XmlPullParser.START_TAG) ( โยนใหม่ IllegalStateException(); ) int ความลึก = 1 ในขณะที่ (ความลึก != 0) ( สวิตช์ (parser. ถัดไป()) ( กรณี XmlPullParser.END_TAG: ความลึก--; ตัวแบ่ง; กรณี XmlPullParser.START_TAG: ความลึก++; ตัวแบ่ง; ) ) )

นี่คือวิธีการทำงาน:

  • เมธอดจะส่งข้อยกเว้นหากเหตุการณ์ปัจจุบันไม่ใช่ START_TAG
  • ใช้ START_TAG และเหตุการณ์ทั้งหมดไม่เกิน END_TAG
  • เพื่อให้แน่ใจว่าแท็กหยุดที่ END_TAG ที่ถูกต้อง และไม่ใช่แท็กแรกที่พบหลังจาก START_TAG เดิม จะติดตามความลึกของการซ้อน

ดังนั้น หากองค์ประกอบปัจจุบันมีองค์ประกอบที่ซ้อนกัน ความลึกจะไม่เป็น 0 จนกว่า parser จะประมวลผลเหตุการณ์ทั้งหมดระหว่าง START_TAG ดั้งเดิมและ END_TAG ที่สอดคล้องกัน ตัวอย่างเช่น พิจารณาว่า parser ข้ามไปอย่างไร องค์ประกอบที่มี 2 องค์ประกอบที่ซ้อนกัน และ :

  • ในครั้งแรกที่ผ่านห่วง while แท็กถัดไปที่ parser พบหลังจาก นี่คือ START_TAG สำหรับ
  • ในการส่งผ่านรอบที่สองผ่านลูป while แท็กถัดไปที่ parser พบคือ END_TAG
  • ในครั้งที่สามผ่านห่วง while แท็กถัดไปที่ parser พบคือ START_TAG . ค่าความลึกเพิ่มขึ้นเป็น 2
  • ในครั้งที่สี่ผ่านห่วง while แท็กถัดไปที่ parser พบคือ END_TAG. ค่าความลึกจะลดลงเหลือ 1
  • ในครั้งที่ห้าและครั้งสุดท้ายผ่านห่วง while แท็กถัดไปที่ parser พบคือ END_TAG. ค่าความลึกลดลงเป็น 0 แสดงว่า ข้ามองค์ประกอบสำเร็จแล้ว

กำลังประมวลผลข้อมูล XML

แอปพลิเคชันตัวอย่างรับและแยกวิเคราะห์ฟีด XML ใน AsyncTask การประมวลผลเสร็จสิ้นนอกเธรด UI หลัก เมื่อประมวลผลเสร็จสิ้น แอปพลิเคชันจะอัปเดตอินเทอร์เฟซผู้ใช้ในกิจกรรมหลัก (NetworkActivity)

ในตัวอย่างด้านล่าง เมธอด loadPage() จะทำสิ่งต่อไปนี้:

  • เริ่มต้นตัวแปรสตริงด้วยค่า URL ที่ชี้ไปที่ฟีด XML
  • เรียกใช้ DownloadXmlTask().execute(url) ใหม่ หากการตั้งค่าของผู้ใช้และการเชื่อมต่อเครือข่ายอนุญาต สิ่งนี้จะสร้างวัตถุ DownloadXmlTask ​​ใหม่ (คลาสย่อย AsyncTask) และดำเนินการเมธอด execute() ซึ่งจะดาวน์โหลดและแยกวิเคราะห์ฟีดและส่งคืนผลลัพธ์สตริงที่จะแสดงในส่วนต่อประสานผู้ใช้
คลาสสาธารณะ NetworkActivity ขยายกิจกรรม (สตริงสุดท้ายแบบคงที่สาธารณะ WIFI = "Wi-Fi"; สตริงสุดท้ายแบบคงที่สาธารณะ ANY = "ใดๆ"; URL สตริงสุดท้ายแบบคงที่ส่วนตัว = "http://stackoverflow.com/feeds/tag?tagnames=android&sort =ใหม่ล่าสุด"; // ไม่ว่าจะมีการเชื่อมต่อ Wi-Fi บูลีนแบบคงที่ส่วนตัว wifiConnected = false; // มีการเชื่อมต่อมือถือหรือไม่ บูลีนแบบคงที่ส่วนตัว mobileConnected = false; // ควรรีเฟรชจอแสดงผลหรือไม่ บูลีนสาธารณะแบบคงที่ refreshDisplay = true; public static String sPref = null; ... // ใช้ AsyncTask เพื่อดาวน์โหลด XML feed จาก stackoverflow.com public void loadPage() ( if((sPref. equals(ANY)) && (wifiConnected || mobileConnected )) ( ใหม่ DownloadXmlTask().execute(URL); ) else if ((sPref.equals(WIFI)) && (wifiConnected)) ( new DownloadXmlTask().execute(URL); ) else ( // แสดงข้อผิดพลาด ) )
  • doInBackground() รันเมธอด loadXmlFromNetwork() มันส่งผ่าน URL ของช่องเป็นพารามิเตอร์ loadXmlFromNetwork() วิธีการรับและประมวลผลช่องทาง เมื่อเสร็จสิ้นการประมวลผล จะส่งสตริงผลลัพธ์กลับ
  • onPostExecute() รับสตริงที่ส่งคืนและแสดงในอินเทอร์เฟซผู้ใช้
// การใช้งาน AsyncTask ที่ใช้ในการดาวน์โหลดฟีด XML จาก stackoverflow.com คลาสส่วนตัว DownloadXmlTask ​​​​ขยาย AsyncTask ( @Override ป้องกัน String doInBackground(String... urls) ( ลอง ( return loadXmlFromNetwork(urls); ) catch (IOException e) ( return getResources().getString(R.string.connection_error); ) catch (XmlPullParserException e) ( return getResources().getString(R.string.xml_error); ) ) @Override protected void onPostExecute(String result) ( setContentView(R.layout.main); // แสดงสตริง HTML ใน UI ผ่าน WebView WebView myWebView = (WebView) findViewById(R.id.webview); myWebView.loadData(ผลลัพธ์ "text/html", null); ) )

ด้านล่างนี้คือเมธอด loadXmlFromNetwork() ซึ่งเรียกจาก DownloadXmlTask ​​​​ มันทำสิ่งต่อไปนี้:

  1. สร้างอินสแตนซ์ของ StackOverflowXmlParser นอกจากนี้ยังสร้างตัวแปรสำหรับออบเจ็กต์ List Entry และ title , url และ Summary เพื่อเก็บค่าที่ดึงมาจากฟีด XML สำหรับฟิลด์เหล่านั้น
  2. เรียก downloadUrl() ซึ่งจะดาวน์โหลดฟีดและส่งคืนเป็น InputStream
  3. ใช้ StackOverflowXmlParser เพื่อแยกวิเคราะห์ InputStream StackOverflowXmlParser เติมข้อมูลรายการด้วยข้อมูลจากฟีด
  4. ประมวลผลรายการ List และรวมข้อมูลฟีดกับมาร์กอัป HTML
  5. ส่งกลับสตริง HTML ที่แสดงในอินเทอร์เฟซผู้ใช้ของกิจกรรมหลัก AsyncTask ในเมธอด onPostExecute()
// อัปโหลด XML จาก stackoverflow.com แยกวิเคราะห์ และรวมเข้ากับ // มาร์กอัป HTML ส่งกลับสตริง HTML สตริงส่วนตัว loadXmlFromNetwork (String urlString) พ่น XmlPullParserException, IOException ( InputStream stream = null; // สร้างอินสแตนซ์ parser StackOverflowXmlParser stackOverflowXmlParser = ใหม่ StackOverflowXmlParser (); รายการ รายการ = null; ชื่อสตริง = null; URL สตริง = null; สรุปสตริง = null; ปฏิทิน rightNow = Calendar.getInstance(); ตัวจัดรูปแบบ DateFormat = SimpleDateFormat ใหม่ ("MMM dd h:mmaa"); // ตรวจสอบว่าผู้ใช้ตั้งค่าการกำหนดค่าตามความชอบเพื่อรวมข้อความสรุป SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences (นี้); บูลีน pref = sharedPrefs.getBoolean ("summaryPref", เท็จ); StringBuilder htmlString = ใหม่ StringBuilder (); htmlString.append("

" + getResources().getString(R.string.page_title) + "

"); htmlString.append(" " + getResources().getString(R.string.updated) + " " + formatter.format(rightNow.getTime()) + ""); ลอง ( stream = downloadUrl(urlString); items = stackOverflowXmlParser.parse(stream); // ตรวจสอบให้แน่ใจว่า InputStream ถูกปิดหลังจากที่แอปนั้น // ใช้งานเสร็จแล้ว ) ในที่สุด ( if (stream != null) ( stream.close(); ) ) // StackOverflowXmlParser ส่งคืนรายการ (เรียกว่า "รายการ") ของวัตถุรายการ // แต่ละวัตถุรายการแสดงถึงโพสต์เดียวในฟีด XML // ส่วนนี้ประมวลผลรายการรายการที่จะรวมแต่ละรายการ รายการด้วยมาร์กอัป HTML // แต่ละรายการจะแสดงใน UI เป็นลิงก์ที่สามารถเลือกรวม // สรุปข้อความ สำหรับ (รายการรายการ: รายการ) ( htmlString. ต่อท้าย ("

" + รายการชื่อ + "

"); // หากผู้ใช้ตั้งค่ากำหนดเพื่อรวมข้อความสรุป // เพิ่มไปที่การแสดงผล if (pref) ( htmlString.append(entry.summary); ) ) return htmlString.toString(); ) // รับการแสดงสตริงของ URL ตั้งค่าการเชื่อมต่อและรับ // อินพุต stream.private InputStream downloadUrl(String urlString) พ่น IOException ( URL url = URL ใหม่ (urlString); HttpURLConnection conn = (HttpURLConnection) url.openConnection() ; conn.setReadTimeout(10000 /* มิลลิวินาที */); conn.setConnectTimeout (15000 /* มิลลิวินาที */); conn.setRequestMethod("GET"); conn.setDoInput(true); // เริ่มการสืบค้น conn.connect( ); ส่งคืน conn.getInputStream(); )