Halo pembaca yang budiman. Posting ini akan fokus pada aplikasi yang sedikit tidak standar dari formalisme terkenal seperti XPath. Semua orang tahu bahwa sangat mudah untuk mengekstraksi informasi dari XML- atau HTML- atau beberapa dokumen * ML lainnya (baik teks sederhana dan beberapa virtual, yang merupakan lapisan teratas untuk mewakili informasi kompleks), kemudian ada untuk mengajukan dokumen-dokumen ini pertanyaan Namun, diketahui bahwa semakin baik pertanyaan dirumuskan, semakin banyak bagian dari jawaban yang sudah ada. Oleh karena itu, pemikiran sederhana menyarankan dirinya: apakah mungkin menggunakan ekspresi yang ditulis dalam XPath sebagai pernyataan, yaitu, membangun dokumen sedemikian rupa sehingga ungkapan XPath ini benar? Saya pikir itu mungkin, dan ini adalah hal pertama yang akan dibahas di sini. Dan yang kedua - jika kita belajar bagaimana secara langsung membuat elemen baru dalam dokumen dengan menggunakan XPath secara langsung, apakah mungkin mengubah XPath menjadi bahasa pemrograman algoritmik yang sederhana? Bahkan, dia tahu cara mengakses data, dia tahu cara membuat data. Sangat mudah untuk membayangkan bagaimana menggambarkan urutan operator dan operator cabang di dalamnya, tetap memikirkan siklus di dalamnya dan tentang fungsi. Ini menarik, setidaknya secara teoritis. Dan ini juga akan dibahas.
Membangun XPath
Jadi, XPath biasa menjelaskan urutan langkah-langkah untuk bergerak melalui pohon dokumen, dan kondisi filter (predikat yang ditulis dalam tanda kurung siku) dapat dikenakan pada setiap langkah. Sebagai hasilnya, kita mendapatkan beberapa set node hingga angka atau string atau nilai logis. Kami terutama tertarik pada kasus beberapa node. XPath biasa menghasilkan node yang sudah ada dalam dokumen. Pertimbangkan membangun XPath hipotetis yang tidak hanya akan mengembalikan node yang ada, tetapi juga membangun node baru sehingga mereka sepenuhnya cocok dengan kueri.
Idenya sangat sederhana - pada langkah berikutnya dari permintaan XPath, kami akan menganalisis predikat filter dan membuat varian data yang termasuk dalam filter ini. Dan kemudian kita akan memeriksa mana dari opsi-opsi ini yang sudah ada dan selesai membangun yang tidak ada.
Sebagai contoh, ini adalah kueri:
/OBJS/Var[@A=1 and @B=1 or @A=2 or @A=3]/X
Jika kami menganggapnya sebagai konstruksi, maka pertama-tama kami akan memeriksa apakah elemen root <OBJS> ada, dan jika tidak, buatlah. Selanjutnya adalah langkah Var dengan filter. Saya tidak akan menjelaskan aturan yang digunakan filter predikat agar tidak menyulitkan presentasi, saya hanya akan mengatakan bahwa filter ini dengan jelas menjelaskan tiga set data yang benar:
- <Var A = β1β B = β1β />
- <Var A = β2β />
- <Var A = β3β />
Jadi, kita perlu memastikan bahwa elemen <OBJS> memiliki elemen <Var> anak dengan data tersebut. Dan, akhirnya, langkah selanjutnya adalah X tanpa syarat - ini berarti bahwa setiap elemen Var harus memiliki elemen turunan <X>.
Jadi, semuanya sederhana. Sebagai hasil menerapkan XPath seperti membangun, misalnya, ke dokumen
<OBJS> <Var A=β2β /> </OBJS>
kami mendapatkan dokumen keluaran:
<OBJS> <Var A=β2β> <X/> </Var> <Var A=β1β B=β1β> <X/> </Var> <Var A=β3β> <X/> </Var> </OBJS>
Dan pada saat yang sama, kami berhasil secara eksklusif dengan XPath, tanpa XSL atau semacamnya.
XPath algoritmik
Jadi kami mengajarkan XPath cara membuat data. Sekarang ajari dia (sedikit) untuk memprosesnya secara algoritmik.
Urutan operator dapat dijelaskan dengan ekspresi AND-logis yang biasa. Ini dihitung ketat dari kiri ke kanan, ini yang Anda butuhkan. Jika harus sepenuhnya diimplementasikan, maka Anda hanya perlu memastikan bahwa semua elemennya mengembalikan ekspresi yang benar.
A and B and C β¦ and Z
Operator kondisional dari bentuk
jika (A) maka B selain
C , tentu saja (dan saya tidak akan mengatakan sesuatu yang baru di sini), dapat dijelaskan dengan ekspresi logis
A and B or C
Semuanya sedikit lebih rumit dengan loop. Saya hanya tidak ingin memperkenalkannya begitu saja, jadi saya memutuskan untuk hanya memperkenalkan konsep fungsi XPath, yang bisa bersifat rekursif. Dan kemudian siklus apa pun dapat direpresentasikan sebagai rantai panggilan rekursif dengan verifikasi kondisi terminasi.
Pada prinsipnya, ini hampir semuanya (dalam versi minimal). Bahkan variabel tidak diperlukan - mereka diganti oleh elemen dokumen saat ini. Hanya argumen fungsi bernama yang diperlukan.
Saya akan memberi contoh. Misalkan kita memiliki dokumen yang berisi dua daftar angka yang dijelaskan oleh serangkaian elemen <list> bersarang:
<a> <b> <list data="1"><list data="2"></list></list> </b> <c> <list data="3"><list data="4"></list></list></c> </a>
Biarkan perlu untuk menggabungkan daftar dari elemen <b> dan elemen <c> dan menempatkan hasilnya secara langsung di <a>. Untuk melakukan ini, tiga fungsi XPath harus diperkenalkan:
concat_list($#, $##): add_list(#/self::*) and add_list(##/self::*) add_list($#): count(list) = 0 and copy_list(#/self::*) or list[add_list(#/self::*)] or true() copy_list($#): count(#/list) = 0 or create(list[@data = #/list/@data]) and (list[copy_list(#/list)] or true())
dan tambahkan XPath panggilan ke mereka:
concat_list(/a/b,/a/c)
Saya harap, para pembaca yang budiman, akan sedikit menarik bagi Anda untuk memahami "kode" seperti itu. Satu-satunya hal yang saya pasti akan sebutkan adalah
create (XPATH) adalah fungsi sistem yang mengeksekusi argumen XPATH dalam mode konstruksi.
Dan sekarang semua ini menarik, tentu saja, tetapi pemrograman tanpa variabel masih cukup sulit. Menyadari hal ini, saya memperkenalkan variabel penuh, yang, pada kenyataannya, di XPath sudah ada - mereka mulai dengan tanda "$", tetapi saya menambahkan kemampuan untuk memberikan nilai kepada mereka dengan fungsi set yang baru. Tolong, di sini adalah contoh fungsi depth_list dengan dua argumen - referensi ke elemen awal yang berisi daftar elemen bersarang (seperti pada contoh di atas), dan variabel output yang berisi panjang daftar:
depth_list($#, &$OUT1): set($OUT1,0) and (#/list[set($OUT1,1) and depth_list(#/list,$OUT0) and set($OUT1,max($OUT0+1,$OUT1))]) or true()
Kesimpulan
Dalam bahasa mikro yang dihasilkan, yang saya sebut
XPath Defender , saya menambahkan beberapa fungsi yang lebih penting dan menggunakannya di sistem saya untuk mengenali dan menghasilkan program PGEN ++ untuk melakukan tugas penting seperti penyelesaian otomatis model program yang disajikan sebagai dokumen XML. Dengan kata lain, jika ada deskripsi tekstual dari suatu masalah (untuk kepastian, dalam bahasa Rusia), untuk solusi yang diperlukan untuk menghasilkan sebuah program, maka deskripsi ini dikenali dan berubah menjadi seperangkat elemen pernyataan tugas yang diurutkan (objek dengan parameter). Ini adalah pernyataan awal, yang belum mengandung rencana untuk menyelesaikan masalah. Elemen yang dikenali ditempatkan dalam dokumen XML dan aturan diterapkan padanya, ditulis baik dalam bentuk ikatan sederhana atau menghasilkan pernyataan XPath, dan dalam bentuk fragmen pada XPath Defender (ini adalah salah satu opsi untuk alur kerja). Aturan-aturan ini memvalidasi dan melengkapi model dokumen XML dengan elemen-elemen rencana solusi. Dan hanya kemudian, sesuai dengan model yang diperoleh, sistem membangun program yang menentukan. Sirkuit ini telah berhasil diuji pada masalah-masalah sederhana dari pemrosesan matematika data vektor.
Namun demikian, hasil yang paling penting, saya pikir, adalah kenyataan bahwa adalah mungkin untuk membuktikan bahwa adalah mungkin untuk membangun bahasa pemrograman algoritmik, menggunakan hampir secara eksklusif cara-cara yang biasa dan membangun XPath, perlu untuk memperkenalkan hanya fungsi.