2016-04-08 7 views
0

Ich möchte eine Ausgabe mit Boxen und XML in Format module drucken. Eine Idee Format ist wie folgt:Boxen und XML im Format Modul

<Events> 
    <Event> 
     <name> haha </name> 
     <name> haha </name> 
    </Event> 
    <Event> 
     <name> lili </name> 
     <name> lili </name> 
    </Event> 
    <Event> 
     <name> lolo </name> 
     <name> lolo </name> 
    </Event> 
</Events> 

Im Moment ist mein Code wie folgt, es nicht genau drucken, was ich erwarte, dass (Ich lasse hier das falsche Ergebnis setzen).

(* in event.ml *) 
    let print_name (fmt: formatter) (x: t) : unit = 
    Format.open_tag "Name"; 
    Format.fprintf fmt "%s" (get_name x); 
    Format.close_tag() 

    (* in events.ml *) 
    let print (fmt: formatter) (x: t) : unit = 
    let print (fmt: formatter) (x: t) : unit = 
     List.iter 
     (fun m -> 
     Format.open_tag "Event"; 
     Format.fprintf fmt "@,@[<v 4>%[email protected],%[email protected]," Event.print_name m 
            Event.print_name m; (* print twice *) 
     Format.close_tag(); 
     Format.fprintf fmt "@,@]") 
     x 
    in 
    Format.open_tag "Events"; 
    Format.fprintf fmt "@,@[<v 4>%[email protected]]@," print x; 
    Format.close_tag() 

    (* in main.ml *) 
    Format.fprintf Format.std_formatter "%a" Events.print x 

Ich bin mir nicht sicher, ob ich die Box gut verstehe, besonders wenn es sich um XML handelt. Weiß jemand, wie man diese Formate richtig schreibt?

Antwort

0

Format ist nützlich, um Daten mit Einrückung zu drucken, aber der Einrückungsalgorithmus ist ein bisschen schwierig und es ist schwierig, andere Einrückungsrichtlinien perfekt zu simulieren. Vielleicht ist es einfacher, Einrückungsebenen selbst zu handhaben.

0

Wie wäre es mit so etwas?

let format, format_list = Format.(fprintf, pp_print_list) (* sorry, hate these cryptic names *) 

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

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 tag name body = Tag (name, body) 
let name s = tag "name" [String s] 

let() = 
    Format.set_margin 50; 

    let xml = tag "Events" [ 
    tag "Event" [ 
     name "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; name "b"; name "c"; 
    ]; 
    tag "Event" [name "a"; name "b"; name "c"]; 
    tag "Event" [name "a"; name "b"]; 
    tag "Event" []; 
    ] in 
    format_xml Format.std_formatter xml 

Hier ist der Ausgang des Testfall oben:

<Events> 
    <Event> 
     <name> 
     aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 
     </name> 
     <name>b</name> 
     <name>c</name> 
    </Event> 
    <Event> 
     <name>a</name> 
     <name>b</name> 
     <name>c</name> 
    </Event> 
    <Event><name>a</name><name>b</name></Event> 
    <Event></Event> 
</Events> 

Durch zwicken den Formatstring @[<hv 3><%s>@,%[email protected];<0 -3></%s>@], können Sie entweder zwingen, horizontal oder vertikal zu legen. Um die genaue Formatierung zu erhalten, die Sie angegeben haben, benötigen Sie das Standard-Tag-Feld, um vertikal zu sein <v 3>, aber Sonderfall Ihre name-Tag-Box horizontal <h> zu sein. Ich habe mich jedoch entschieden, ein allgemeines Beispiel zu geben.

Lassen Sie mich erklären. @[<hv 3> öffnet eine Box, die zwischen horizontalen h und vertikalen v Layouts wechseln kann, je nachdem, ob der Inhalt der Box in eine einzelne Zeile passt, in unserem Fall 50 Zeichen (siehe Format.set_margin 50). 3 in @[<hv 3> ist die Einrückungsebene. <%s> ist das öffnende XML-Tag, </%s> -closing. Das öffnende Tag befindet sich in der Box, es ist jedoch nicht eingerückt, da der Einzug nur bei Unterbrechungshinweisen wie @, eingeführt wird. Wir möchten, dass das schließende Tag nicht eingerückt wird, deshalb stellen wir einen Unterbrechungshinweis @;<0 -3> vor, der im Fall des vertikalen Layouts -3 entfernt, aber 0 Leerzeichen in die Horizontale einführt. Beachten Sie, dass Format.pp_print_list, die ich verwende, die Hinweise zwischen den Listenelementen @, vorgibt (standardmäßig).

Ich hoffe, das ist nützlich. Lass es mich wissen, falls du fragen hast.

0

Sie verarbeiten den Einzug mit Boxen. Um diese Vertiefung zu erkennen Sie müssen Kisten wie folgt verwenden (Pars umreißen Boxen):

((<tag>contents)</tag>) 

Hinweis, wie Boxen und Tags sind unterschiedlich verschachtelt.Diese Technik wird in Gasoline gebraucht:

Beachten Sie, dass die authorkit von Benzin zum Schreiben von einfachen Ad-hoc-nützlich ist SGML Dateien, aber in fortgeschrittenen Zeiten, Bibliotheken aus der ocsigen Projekte sind wahrscheinlich nützlicher (aber schwieriger zu verwenden).