2013-10-26 4 views
1

Я пытаюсь вывода XML с OCaml с отступом:вывода XML с модулем Формат OCaml

<document> 
     <tag> 
      <undertag/> 
      <undertag/> 
     </tag> 
     <tag> 
      <undertag/> 
     </tag> 
</document> 

Я пытаюсь с форматом, но я не могу получить ожидаемый результат ...

Format.printf "@."; 
    Format.printf 
    "@[<hv>@[<hv 2>(------------------------------------------------------------------------\ 
    @[<hv>@[<hv 2>(------------------------------------------------------------------------\ 
    @[<hv>@[<hv 2>(------------------------------------------------------------------------\ 
    @]@,)@]@]@,)@]@]@,)@]"; 
    Format.printf "@." 

ли выход:

(------------------------------------------------------------------------ 
    (------------------------------------------------------------------------ 
    (------------------------------------------------------------------------ 
    ) 
) 
) 

Но

fp "@."; 
fp "@[<hv>@[<hv 2><document>"; 
fp "@[<hv>@[<hv 2><cfun>"; 
fp "@[<hv>@[<hv 2><cst/>@]@]"; 
fp "@]@,</cfun>@]"; 
fp "@]@,</document>@]"; 
fp "@."; 

Где fp = Format.printf выходы <document><cfun><cst/></cfun></document> (все в одной строке!).

Как мне это сделать?

Спасибо.

ответ

3

Пример использования xmlm (намеренно процедурных, используйте вспомогательные функции, подходящие для Вашего случая):

let out = Xmlm.make_output ~indent:(Some 4) (`Channel stdout) in 
Xmlm.output out (`Dtd None); 
Xmlm.output out (`El_start (("", "document"), [])); 
Xmlm.output out (`El_start (("", "tag"), [])); 
Xmlm.output out (`El_start (("", "undertag"), [(("", "id"), "1")])); 
Xmlm.output out (`Data "data"); 
Xmlm.output out `El_end; 
Xmlm.output out (`El_start (("", "undertag"), [(("", "id"), "2")])); 
Xmlm.output out `El_end; 
Xmlm.output out `El_end; 
Xmlm.output out `El_end 

Обратите внимание на отступа параметр.

Выход:

<?xml version="1.0" encoding="UTF-8"?> 
<document> 
    <tag> 
     <undertag id="1"> 
      data 
     </undertag> 
     <undertag id="2"/> 
    </tag> 
</document> 
+0

Спасибо, но я предпочел бы придерживаться стандартной библиотеки, так как это единственное, что мне разрешено. Поэтому я хотел бы понять, как работает формат. –

0

Вы можете использовать @\n для обеспечения разрывы строк. Для @, или @ макет будет стараться максимально вписываться в строку, но если разрывает линию, она разбивает последующие строки в том же окне печати. Поэкспериментируйте с ним. См. documentation и guidelines.

+0

Да, я прочитал его, но он сказал, используя @ \ n означает, что вы не использовали правильные прямоугольники ... –

+0

Если вам нужен разрыв строки, используйте его. Выше был комментарий стиля. – lukstafi

2

Друг показал мне способ сделать это с помощью вертикальных коробок. Следующие выходы просто отлично: @[<v 0>@,<xml>@,<document>@[<v 2>@,<tag>@[<v 2>@,<el>@,<el>@,<el>@]@,</tag>@]@,</document>@].

Надеюсь, это поможет.

2

Вы можете выполнить следующие действия с помощью модуля Формат:

Допустим, у вас есть этот тип XML,

type xml = 
    | Tag of string * xml list 
    | String of string 

let tag name body = Tag (name, body) 

Вот довольно-принтер для него:

let format, format_list = Format.(fprintf, pp_print_list) 

let rec format_xml f = function 
    | Tag (name, body) -> 
     let format_body = format_list format_xml in 
     format f "@[<hv 3><%s>@,%[email protected];<0 -3></%s>@]" name format_body body name 
    | String text -> format f "%s" text 

Вот тест аналогичный вашему:

let() = 
    Format.set_margin 30; 

    let xml = tag "document" [ 
    tag "tag" [tag "undertag" [String "hello"]]; 
    tag "tag" [tag "undertag" []]; 
    ] in 
    format_xml Format.std_formatter xml 

Он печатает следующее:

<document> 
    <tag> 
     <undertag> 
     hello 
     </undertag> 
    </tag> 
    <tag> 
     <undertag></undertag> 
    </tag> 
</document> 

Другой мой ответ имеет еще некоторые пояснения по строке формата, который используется: Boxes and XML in Format module

Смежные вопросы