برنامه نویسی

ساخت خروجی XML با dream-html

مدتی است که من یک کتابخانه OCaml به نام dream-html نگهداری می کنم. این کتابخانه در درجه اول برای ارائه HTML، SVG و MathML به درستی ساخته شده است. اخیراً قابلیت رندر کردن نشانه‌گذاری XML به خوبی شکل گرفته را اضافه کردم که قوانین کمی متفاوت از HTML دارد. به عنوان مثال، در HTML اگر می خواهید خالی بنویسید div برچسب، شما انجام می دهید: . But according to the rules of XML, you could also write ie a self-closing tag, however HTML 5 does not have the concept of self-closing tags!

So by having the library take care of these subtle but crucial details, you can just concentrate on writing code that generates the markup. Of course, this has many other advantages too, but in this post I will just look at XML.

It turns out that often we need to serialize some data into XML format, for storage or communication purposes. There are a few packages in the OCaml ecosystem which handle XML, however I think dream-html actually does it surprisingly well now. Let’s take a look.

But first, a small clarification about the dream-html package itself. Recently I split it up into two packages:

  1. pure-html تمام قابلیت های مورد نیاز برای نوشتن HTML و XML معتبر را دارد
  2. dream-html همه موارد فوق را دارد، به علاوه مقداری ادغام با چارچوب وب Dream برای سهولت استفاده.

همانطور که ممکن است تصور کنید، دلیل تقسیم اجازه استفاده از عملکرد HTML/XML بسته بدون نیاز به کشیدن کل مخروط وابستگی Dream بود، که بسیار بزرگ است، به خصوص اگر از مخروط وابستگی متفاوتی استفاده کنید. خوب. بنابراین pure-html فقط به uri بسته ای برای کمک به ساخت رشته های URI صحیح.

برای شروع استفاده از آن، فقط نصب کنید: opam install pure-html

و به خود اضافه کنید dune فایل: (libraries pure-html)

حال، بیایید به مثالی نگاه کنیم که چگونه می توانید از آن برای ساخت XML استفاده کنید. فرض کنید نوع زیر را دارید:

type person = {
  name : string;
  email : string;
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

و شما باید آن را به صورت سریال XML به صورت زیر انجام دهید:

 name="Bob" email="bob@info.com"/>
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

بیایید با استفاده از یک سریال ساز بنویسیم pure-html بسته:

open Pure_html

let person_xml =
  let person = std_tag "person"
  and name = string_attr "name"
  and email = string_attr "email" in
  fun { name = n; email = e } -> person [name "%s" n; email "%s" e] []
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

بیایید آن را آزمایش کنیم:

$ utop -require pure-html
# open Pure_html;;
# let pp = pp_xml ~header:true;;
val pp : Format.formatter -> node -> unit = 
# #install_printer pp;;
# type person = {
  name : string;
  email : string;
};;
type person = { name : string; email : string; }
# let person_xml =
  let person = std_tag "person"
  and name = string_attr "name"
  and email = string_attr "email" in
  fun { name = n; email = e } -> person [name "%s" n; email "%s" e] [];;
val person_xml : person -> node = 
# person_xml { name = "Bob"; email = "bob@example.com" };;
- : node =


وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

خوب خوب، پس ما person رکورد به این روش خاص سریال می شود. اما، اگر بخواهیم آن را سریالی کنیم، چه می‌شود:


  Bob
  bob@example.com

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

از این گذشته، این یک روش رایج برای قالب‌بندی رکوردها در XML است. بیایید سریال ساز را به این سبک بنویسیم:

let person_xml =
  let person = std_tag "person"
  and name = std_tag "name"
  and email = std_tag "email" in
  fun { name = n; email = e } ->
    person [] [
      name [] [txt "%s" n];
      email [] [txt "%s" e];
    ]
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

بیایید آن را امتحان کنیم:

# let person_xml =
  let person = std_tag "person"
  and name = std_tag "name"
  and email = std_tag "email" in
  fun { name = n; email = e } ->
    person [] [
      name [] [txt "%s" n];
      email [] [txt "%s" e];
    ];;
val person_xml : person -> node = 
# person_xml { name = "Bob"; email = "bob@example.com" };;
- : node =

Bobbob@example.com
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

به نظر خوب میاد! بیایید توابع را بررسی کنیم pure-html بسته مورد استفاده در اینجا برای رسیدن به این.

std_tag

این تابع به ما امکان می دهد یک تگ سفارشی تعریف کنیم: let person = std_tag "person". توجه داشته باشید که اضافه کردن فضای نام امری بی اهمیت است: let person = std_tag "my:person".

string_attr

این به ما اجازه می دهد تا یک ویژگی سفارشی را تعریف کنیم که a را می گیرد رشته ظرفیت ترابری: let name = string_attr "name". باز هم اضافه کردن فضای نام آسان است: let name = string_attr "my:name".

توابع تعریف ویژگی دیگری نیز وجود دارد که اجازه می دهد int محموله ها و غیره برای جزئیات به اسناد بسته مراجعه کنید.

pp_xml

این به ما امکان می دهد چاپگری را تعریف کنیم که XML را مطابق قوانین نحوی آن به درستی رندر می کند:

let pp = pp_xml ~header:true
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

اختیاری header آرگومان به ما اجازه می دهد مشخص کنیم که آیا می خواهیم همیشه سربرگ XML را چاپ کنیم یا خیر. در بسیاری از موارد سریال سازی، ما انجام می دهیم.

همچنین یک تابع مشابه وجود دارد که به جای تعریف a چاپگر، فقط تبدیل می کند گره ساخته شده در یک رشته به طور مستقیم: to_xml.

نتیجه

با این توابع اساسی، ممکن است دقیقا کنترل کنید که XML سریالی چگونه به نظر می رسد. توجه داشته باشید که dream-html و pure-html فقط پشتیبانی سریال سازی داده ها به فرمت XML، و نه سریال زدایی یعنی تجزیه XML. برای آن، بسته های دیگری وجود دارد!

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا