Я ищу простой пример для модуля ppx_xml_conv из janestreet. Я не очень хорошо знаком с (относительно) новой ppx-вещью и не могу понять ее из исходного кода. В конечном счете, я пытаюсь написать клиент для старой службы SOAP и хочу превратить xsd (из wsdl) в тип и сериализатор/десериализатор.Есть ли примеры использования для OCaml ppx_xml_conv модуля
ответ
Поскольку есть bug in ppx_xml_conv, я приведу пример для ppx_sexp_conv, который работает тождественно.
$ cat a.ml
open Sexplib.Std
type attr = {
attr_id : string;
attr_path : string;
attr_value : string;
} [@@deriving sexp]
$ cat a.mli
type attr = {
attr_id : string;
attr_path : string;
attr_value : string;
} [@@deriving sexp]
$ ocamlfind ocamlc -package sexplib,ppx_sexp_conv -dsource -c a.mli
type attr = {
attr_id: string;
attr_path: string;
attr_value: string;}[@@deriving sexp]
val attr_of_sexp : Sexplib.Sexp.t -> attr
val sexp_of_attr : attr -> Sexplib.Sexp.t
$ ocamlfind ocamlc -package sexplib,ppx_sexp_conv -dsource -c a.ml
(* ... long output ... *)
Я использовал -dsource
флаг, так что вы можете увидеть сгенерированные. Обратите внимание, что нет необходимости создавать исполняемый файл ppx и вызывать его отдельно. Компиляция с пакетом ppx_sexp_conv
приводит к тому, что расширение ppx пакета автоматически применяется.
В качестве другого примера вот исполняемым:
$ cat b.ml
open Sexplib.Std
type attr = {
attr_id : string;
attr_path : string;
attr_value : string;
} [@@deriving sexp]
let x = {attr_id="abc"; attr_path="foo/bar"; attr_value="something"}
let() = Printf.printf "sexp: %s\n" (Sexplib.Sexp.to_string (sexp_of_attr x))
$ ocamlfind ocamlc -package sexplib,ppx_sexp_conv -linkpkg b.ml
$ ./a.out
sexp: ((attr_id abc)(attr_path foo/bar)(attr_value something))
Удивительный, это очень полезно. Благодарю. –
Для тех из вас, кто, как и я, склоняется к невежеству, я бы рекомендовал посмотреть на readme для [ppx_driver] (https://github.com/janestreet/ppx_driver).
Подводя итог, хотя, основной procecure есть первый построить драйвер (заменить -package ppx_sexp_conv -package ppx_bin_prot
с модулями преобразования, которые вы используете):
$ ocamlfind ocamlopt -predicates ppx_driver -o ppx -linkpkg \
-package ppx_sexp_conv -package ppx_bin_prot \
ppx_driver_runner.cmxa
Это даст вам ppx
исполняемый файл. Запуск этого файла в исходном файле приведет к сбросу расширенной версии источника.
$ ./ppx -help
ppx [extra_args] [files] ...
$ ./ppx src/myFile.ml
Тогда этот исполняемый файл может использоваться как препроцессор при строительстве.
$ ocamlc -c -pp ./ppx src/myFile.ml
Мой источник был
type attr = {
attr_id : string;
attr_path : string;
attr_value : string;
} [@@deriving xml]
и препроцессор добавил to_xml t
и from_xml xml
функции.
Как уже отмечалось выше, это все, что вам нужно, поскольку в структуре ppx_driver все еще есть некоторые нерешенные проблемы.
Вам не нужно генерировать исполняемый файл и вызывать его отдельно. Есть способ заставить компилятор сделать это внутренне. Я отправлю пример. –
Я собирался отправить ответ, но не может заставить его работать сам. Я [сообщил] (https://github.com/janestreet/ppx_xml_conv/issues/1). В то же время обратите внимание, что все пакеты ppx _ * _ Jane Street работают аналогично. Поскольку ppx_sexp_conv является наиболее часто используемым, google'ing для него приведет к большему количеству результатов. [Ppx_variants_conv] (https://github.com/janestreet/ppx_variants_conv) имеет README, который дает пример. –
Это дало мне именно то, что мне было нужно. Я тоже сейчас дошел до «Error: Unbound module Fields». Я видел проблему (и ответ) на github, поэтому я, вероятно, подожду, пока структура ppx_driver немного более стабильна. –