XML กับ Polymorphism

  • warning: realpath() [function.realpath]: SAFE MODE Restriction in effect. The script whose uid is 1005 is not allowed to access /tmp owned by uid 0 in /var/www/sites/sugree/codenone.com/subdomains/www/html/includes/file.inc on line 190.
  • warning: realpath() [function.realpath]: SAFE MODE Restriction in effect. The script whose uid is 1005 is not allowed to access /tmp owned by uid 0 in /var/www/sites/sugree/codenone.com/subdomains/www/html/includes/file.inc on line 190.

ผมมี xml ที่ห่อ xml อื่นไว้อีกที (envelope) มันจะมีวิธีไหนมั้ยครับที่จะออกแบบ xml นี้ให้ทำงานแบบ Polymorphism คือสามารถตรวจสอบว่า payload นี้เป็นอะไร เพื่อจะเขียนโปรแกรม process payload นั้นได้ถูกต้อง (คล้ายๆ SOAP ที่หุ้ม xml อื่นไว้อีกที)

ถ้ายังไม่เห็นภาพลองดูที่ xml สองตัวนี้ ผมจะรู้ได้ยังไงว่า payload เป็น content_a หรือ content_b xml namespace จะช่วยได้ไหมครับ

<myXML>
  <id>1234</id>
  <payload>
    <content_a></content_a>
  </payload>
</myXML>
<myXML>
  <id>1234</id>
  <payload>
    <content_b></content_b>
  </payload>
</myXML>

ไม่ถนัดเรื่องนี้ กับไม่เข้าใจคำถามนัก
แต่ลองมา brain strom (หรือมั่ว) กันดีกว่า

namespace น่าจะช่วยเรื่อง name conflict กับ extension มากกว่านะ

กรณีที่ใช้ DOM parse
เราก็น่าจะเขียนได้ดังนี้

require 'rexml/document'     
x = "<myXML><id>1234</id><payload><content_a></content_a></payload></myXML>" 
doc = REXML::Document.new x
if doc.elements["/myXML/payload"][0].name == 'content_a'
  process_a 
else ...
  ...
end
sugree's picture

มันต้องสนด้วยเหรอครับว่าข้างในเป็นอะไร เพราะตอนใช้ก็รู้อยู่แล้วว่ามันคืออะไร ถ้าอยากจะ validate ก็ใช้ relaxng ระบุไปว่าข้างในเป็นอะไรได้บ้าง

ผมเข้าใจคำถามถูกรึเปล่าครับ

nontster's picture

คล้ายๆกับว่า payload มันมีได้หลายแบบ ซึ่งแต่ละแบบเราต้องเขียนโปรแกรม parse สมมติว่า payload เป็นรายการหนังสือ เราก็เขียน โปรแกรม parse xml นี้แล้ว insert เข้า database book ถ้า payload เป็น รายการอาหาร เราก็เขียนโปรแกรม parse xml นี้เพื่อ insert ข้อมูลลงในตาราง food เป็นต้นครับ

ผมคิดว่า namespace น่าจะช่วยได้ แต่ว่าเราควรใส่ namespace ไว้ยังไง ยังนึกไม่ออกครับ ^^"

ทำแบบนี้ได้ไหมครับ

<myXML>
  <id>1234</id>
  <payload xmlns="book">
    <content_b></content_b>
  </payload>
</myXML>
sugree's picture

น่าจะแบบนี้

<myXML>
  <id>1234</id>
  <payload>
    <p:content_b xmlns:p="book"></p:content_b>
  </payload>
</myXML>

ns ใช้เพื่อให้ element มันซ้ำกันได้ อย่างข้างบน อาจจะทำแปลกๆ แบบนี้

<myXML>
  <id>1234</id>
  <payload>
    <p:myXML xmlns:p="book"></p:myXML>
  </payload>
</myXML>

ตอนอ่านเราแค่ต้องการทุกอย่างใต้ payload เท่านั้นเองนี่ครับ ใช้ XPath ก็ได้ แล้วค่อยดูว่ามันเป็น ns อะไร element อะไร

ใส่ที่ tag นอกสุด ก็ได้
แต่ไหนๆ จะใช้ namespace แล้ว ก็ควรจะ declare namespace ของ wrapper ด้วย

<myxml xmlns="http://nonster/myxml"
       xmlns:b="http://nonster/b">
  <id>1234</id>
  <payload>
    <b:content>yyy</b:content>
  </payload>
<myxml>
nontster's picture

ขอบคุณ sugree กับ พี่ป๊อกมากครับ @^_^@

ย้าย Codenone

ประกาศย้าย Codenone ไปใช้ Forum ของ Blognone แทนครับ ตามไปตั้งกระทู้ต่อได้ที่ Codenone Forum (รายละเอียดอ่านจากกระทู้ ย้าย Codenone ไปรวมกับ Blognone)

กระทู้เก่าๆ จะย้ายตามไปในภายหลัง ตอนนี้ปิดการโพสต์กระทู้ไว้ เหลือไว้เฉพาะอ้างอิงเท่านั้น