วิธีใช้งาน xml บน php4 โดยใช้ DOM แบบเบื่องต้น


ดูตัวอย่าง Code ก่อนละกัน แล้วค่อยเป็นค่อยไปนะครับ

<?php

/******* นี้เป็นตัวอย่างเอกสารที่เป็น xml นะครับ ********/
  $xml_string = "
  "<?xml version='1.0'?>
   <Order>
     <BuyerID>1</BuyerID>
     <Staff>
       <StaffID>12</StaffID>
       <StaffName>aadfor</StaffName>
     </Staff> 
     <DueDate>12-30-23</DueDate>
     <OrderList>
       <OrderItem>
         <ItemID>1</ItemID>
         <Amount>20</Amount>
       </OrderItem>
       <OrderItem>
         <ItemID>2</ItemID>
         <Amount>30</Amount>
       </OrderItem>
       <OrderItem>
         <ItemID>3</ItemID>
         <Amount>40</Amount>
      </OrderItem>
      <OrderItem>
         <ItemID>4</ItemID>
         <Amount>50</Amount>
      </OrderItem>
     </OrderList>
  </Order>";

/**********ตัวโปรแกรมเริ่มตรงนี้ละกัน **********/

  // อ่านเอกสาร ที่เป็น xml และทำการตรวจสอบ
  if(!$doc = xmldoc($xml_string))
   die("Error passing XML");

// กำหนดตัวแปร Root เริ่มต้นอ่านเอกสาร
  $root = $doc->root();

// ลงไปลึก 1 ระดับเพื่อจะอ่านข้อมูล Element ของลูก ๆ
  $children = $root->children();

// ตัวแปร $children จะเป็น อาร์เรย์ ดังนั้นจึงสามารถใช้ foreach ท่องไปยังแต่ละ element ภายในเอกสารได้ ในที่นี้ให้ตัวแปร $child เก็บ element ค่า element ที่กำลังท่องอยู่
  foreach($children as $child)
  {

   // ต้องทำการตรวจสอบ type ของ element ว่าเป็น XML_ELEMENT_NODE รึเปล่า รายละเอียดค่อยกล่าวเพิ่มเติมในท้ายเอกสาร ซึ่งในที่นี้เราจะสนใจเฉพาะ element ชนิดนี้ก่อน
   if ($child->type == XML_ELEMENT_NODE)
   {

    //ตรวจสอบป้ายของ element ว่ามีป้ายเป็นอะไรโดยใช้ property tagname ในการตรวจสอบ
    switch($child->tagname) {

      //ในกรณีป้ายเป็น BuyerID
     case "BuyerID":

      // ใน BuyerID นั้นไม่มี element อื่น ๆ ภายใน (ตัวมันเองเก็บ Content) ดังนั้นเราจึงสามารถดึง Content มาได้เลย ซึ่งจะต้องรับค่ามาจาก childrent อีกที วิธีการดึงให้ดูจาก code ละกัน 
      $text = $child->children();
      $BuyerID = $text[0]->content;
      echo $child->tagname." = ".$BuyerID."<br>";
      break;

     //ในกรณีป้ายเป็น Staff
     case "Staff":

       //ป้ายนี้จะมีลูกอยู่ภายในอีก 1 ชั้น ดังนั้นเราจึงต้องเข้าไปอีก 1 ชั้นโดยใช้คำสั่ง children อีกครั้ง
       $staffNode = $child->children();

       //เหมือนกับข้างต้นที่กล่าวมาแล้วคือ element ที่ได้นั้นจะเป็นอาร์เรย์ดังนั้นเราจึงสามารใช้ foreach เพื่อจะเข้าถึง element แต่ละตัวภายใน node นี้ ในที่นี้เราใช้ตัวแปร $staffElement element ที่กำลังท่องอยู่ในขณะนั้น
       foreach($staffNode as $staffElement) {

       //ตรวจสอบชนิดที่เป็น XML_ELEMENT_NODE
       if ($staffElement->type == XML_ELEMENT_NODE) {


        //ตรวจสอบป้ายของ element และเก็บค่าเข้าตัวแปรพร้อมพิมพ์ (ขอไม่อธิบายรายละเอียด เนื่องจากเหมือนข้างบน)
        if($staffElement->tagname == "StaffID") {
         $text = $staffElement->children();
         $staffID = $text[0]->content;
         echo $staffElement->tagname." = ".$staffID."<br>";
        } else
        if($staffElement->tagname == "StaffName") {
         $text = $staffElement->children();
         $staffName = $text[0]->content;
         echo $staffElement->tagname." = ".$staffName."<br>";
        }

        //ในกรณีเจอป้ายที่ไม่ประกาศไว้แสดงว่าเอกสารผิดพลาด ก็เลยให้มันจบการทำงานเสีย
        else die("ERROR:Invalid format!");
       }
      }
      break;

     // กรณีป้ายเป็น DueDate เหมือนกับป้าย BuyerID 
     case "DueDate":
      $text = $child->children();
      $DueDate = $text[0]->content;
      echo $child->tagname." = ".$DueDate."<br>";
      break;

     // กรณีป้าย OrderList  ป้ายนี้จะมีลูกอยู่ 2 ระดับชั้น คือ OrderItem คือชั้นที่ 1 และ ภายใน OrderItem ก็จะเป็นรายละเอียดคือ ItemID และ Amount เป็นชั้นที่สอง ซึ่งเราจะต้องเข้าไปทีละชั้นเพื่อที่จะเข้าไปกับข้อมูลมา ลองทำความเข้าใจเพิ่มเติมดูนะครับ (ถึงตรงนี้แล้วไม่น่าจะยาก)

     case "OrderList":
      $orderList = $child->children();
      foreach ($orderList as $orderListElement) {
       if ($orderListElement->type == XML_ELEMENT_NODE) {
        if ($orderListElement->tagname == "OrderItem") {

         $orderItem = $orderListElement->children();
         foreach($orderItem as $orderItemElement) {
          if ($orderItemElement->type == XML_ELEMENT_NODE) {
           if ($orderItemElement->tagname == "ItemID") {
            $text = $orderItemElement->children();
            $itemID = $text[0]->content;
           } else
           if ($orderItemElement->tagname == "Amount") {
            $text = $orderItemElement->children();
            $amount[$itemID] = $text[0]->content;
           }
           else die("ERROR:Invalid format!");
          }
         }
                  echo "Item: ".$itemID." - ".$amount[$itemID]."<br>";
        }
       }
       }
      break;
     default: die("ERROR:Invalid format!");
    }
    }
  }
/**************************** End Read XML ********************************/
?>

เมื่อสั่งทำงานจะแสดงผลดังนี้

BuyerID = 1
StaffID = 12
StaffName = aadfor
DueDate = 12-30-23
Item: 1 - 20
Item: 2 - 30
Item: 3 - 40
Item: 4 - 50

 ข้อมูลเพิ่มเติม
ชนิดของข้อมูลมีดังนี้ครับ

Integer

Node type

Description

1

XML_ELEMENT_NODE

Element

2

XML_ATTRIBUTE_NODE

Attribute

3

XML_TEXT_NODE

Text

4

XML_CDATA_SECTION_NODE

CDATA section

5

XML_ENTITY_REF_NODE

Entity reference

7

XML_PI_NODE

Processing instruction

8

XML_COMMENT_NODE

Comment

9

XML_DOCUMENT_NODE

XML document

12

XML_NOTATION_NODE

Notation

รายละเอียด เอาเท่าที่รู้ตอนนี้นะครับ
element 1-3 ก็มีความหมายตามตัวเลยครับ ซึ่งได้แก่ element attribute และ text แต่มีข้อสังเกตเพิ่มเติม โดยให้ลองทดสอบ code ต่อไปนี้

<?php
  $xml_string = "
<root>
   text_root1
   <child1>text_child1</child1>
   text_root2
   <child2 attr='text_child_attribute'>text_child2</child2>
   text_root3
</root>";

  if(!$doc = xmldoc($xml_string))
   die("Error passing XML");
  $root = $doc->root();
  $children = $root->children();
  foreach($children as $child)
 {
  switch($child->type){
   case XML_ELEMENT_NODE:
    $text = $child->children();
    echo "XML_ELEMENT_NODE:".$child->tagname." CONTENT:".$text[0]->content."<br>";
    if ($child->get_attribute("attr"))
     echo "&nbsp;&nbsp;&nbsp;ATTRIBUTE:".$child->get_attribute("attr")."<br>";
    break;
   case XML_TEXT_NODE:
     echo "XML_TEXT_NODE:".$child->content."<br>";
    break;
   default:
    echo "ORTHER ELEMENT:";
     print_r($child);
    echo "<br>";
  }
 }
?>

 ผลการทำงานที่ได้

XML_TEXT_NODE: text_root1
XML_ELEMENT_NODE:child1 CONTENT:text_child1
XML_TEXT_NODE: text_root2
XML_ELEMENT_NODE:child2 CONTENT:text_child2
   ATTRIBUTE:text_child_attribute
XML_TEXT_NODE: text_root3

จากผลการทำงานจะเห็นได้ว่า ทุกๆ ครั้งที่เราเข้าไปใน element นั้นจะมี element ชนิด XML_TEXT_NODE คั้นระหว่างแต่ละ element แม้ว่าในเอกสาร xml ที่เราดำเนินการด้วยนั้นจะไม่มี element นั้นก็จะมี content เป็น string ว่างแทน

 

คำสำคัญ (Tags): #dom#xml#php
หมายเลขบันทึก: 49239เขียนเมื่อ 9 กันยายน 2006 23:23 น. ()แก้ไขเมื่อ 15 มิถุนายน 2012 15:55 น. ()สัญญาอนุญาต: จำนวนที่อ่าน


ความเห็น

ไม่มีความเห็น

พบปัญหาการใช้งานกรุณาแจ้ง LINE ID @gotoknow
ClassStart
ระบบจัดการการเรียนการสอนผ่านอินเทอร์เน็ต
ทั้งเว็บทั้งแอปใช้งานฟรี
ClassStart Books
โครงการหนังสือจากคลาสสตาร์ท