Add support for attribute nodes. Correctly escape special charaters
authorKim Nguyễn <kn@lri.fr>
Thu, 28 Jun 2012 16:46:53 +0000 (18:46 +0200)
committerKim Nguyễn <kn@lri.fr>
Thu, 28 Jun 2012 16:46:53 +0000 (18:46 +0200)
during printing.

src/tree.ml

index f914d33..4d01403 100644 (file)
@@ -101,6 +101,7 @@ struct
 
 
   let text_string = QName.to_string QName.text
 
 
   let text_string = QName.to_string QName.text
+  let attr_map_string = QName.to_string QName.attribute_map
 
   let rec start_element_handler parser_ ctx tag attr_list =
     do_text parser_ ctx;
 
   let rec start_element_handler parser_ ctx tag attr_list =
     do_text parser_ ctx;
@@ -115,7 +116,21 @@ struct
     in
     if parent.first_child == dummy then parent.first_child <- n
     else parent.next_sibling <- n;
     in
     if parent.first_child == dummy then parent.first_child <- n
     else parent.next_sibling <- n;
-    push n ctx
+    push n ctx;
+    match attr_list with
+      [] -> ()
+    | _ ->
+      start_element_handler parser_ ctx attr_map_string [];
+      List.iter (do_attribute parser_ ctx) attr_list;
+      end_element_handler parser_ ctx attr_map_string
+
+  and do_attribute parser_ ctx (att, value) =
+    let att_tag = " " ^ att in
+    start_element_handler parser_ ctx att_tag [];
+    start_element_handler parser_ ctx text_string [];
+    let n = top ctx in n.data <- value;
+    end_element_handler parser_ ctx text_string;
+    end_element_handler parser_ ctx att_tag
 
   and consume_closing ctx n =
     if n.next_sibling != dummy then
 
   and consume_closing ctx n =
     if n.next_sibling != dummy then
@@ -124,7 +139,7 @@ struct
   and end_element_handler parser_ ctx tag =
     do_text parser_ ctx;
     let node = top ctx in
   and end_element_handler parser_ ctx tag =
     do_text parser_ ctx;
     let node = top ctx in
-    if nodef.first_child == dummy then node.first_child <- nil
+    if node.first_child == dummy then node.first_child <- nil
     else begin
       node.next_sibling <- nil;
       consume_closing ctx node
     else begin
       node.next_sibling <- nil;
       consume_closing ctx node
@@ -193,20 +208,49 @@ end
 let load_xml_file = Parser.parse_file
 let load_xml_string = Parser.parse_string
 
 let load_xml_file = Parser.parse_file
 let load_xml_string = Parser.parse_string
 
+
+let output_escape_string out s =
+  for i = 0 to String.length s - 1 do
+    match s.[i] with
+    | '<' -> output_string out "&lt;"
+    | '>' -> output_string out "&gt;"
+    | '&' -> output_string out "&amp;"
+    | '"' -> output_string out "&quot;"
+    | '\'' -> output_string out "&apos;"
+    | c -> output_char out c
+  done
+
+let rec print_attributes out tree_ node =
+  if node != nil then begin
+    output_string out (QName.to_string node.tag);
+    output_string out "=\"";
+    output_escape_string out node.first_child.data;
+    output_char out '"';
+    print_attributes out tree_ node.next_sibling
+  end
+
 let rec print_xml out tree_ node =
   if node != nil then
     let () =
       if node.tag == QName.text then
 let rec print_xml out tree_ node =
   if node != nil then
     let () =
       if node.tag == QName.text then
-        output_string out node.data
+        output_escape_string out node.data
       else
         let tag = QName.to_string node.tag in
         output_char out '<';
         output_string out tag;
       else
         let tag = QName.to_string node.tag in
         output_char out '<';
         output_string out tag;
-      (* print attributes *)
-        if node.first_child == nil then output_string out "/>"
+        let fchild =
+          if node.first_child.tag == QName.attribute_map then
+            let () =
+              print_attributes out tree_ node.first_child.first_child
+            in
+            node.first_child.next_sibling
+          else
+            node.first_child
+        in
+        if fchild == nil then output_string out "/>"
         else begin
           output_char out '>';
         else begin
           output_char out '>';
-          print_xml out tree_ node.first_child;
+          print_xml out tree_ fchild;
           output_string out "</";
           output_string out tag;
           output_char out '>'
           output_string out "</";
           output_string out tag;
           output_char out '>'