File : dom-core-nodes-output.adb
------------------------------------------------------------------------------
-- ADAGIO - ADALID - AENEA. --
-- --
-- Copyright (C) 2003 --
-- A. Mosteo. --
-- --
-- Authors: A. Mosteo. (adagio@mosteo.com) --
-- --
-- If you have any questions in regard to this software, please address --
-- them to the above email. --
-- --
-- This program is free software; you can redistribute it and/or modify --
-- it under the terms of the GNU General Public License as published by --
-- the Free Software Foundation; either version 2 of the License, or (at --
-- your option) any later version. --
-- --
-- This program is distributed in the hope that it will be useful, but --
-- WITHOUT ANY WARRANTY; without even the implied warranty of --
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU --
-- General Public License for more details. --
-- --
-- You should have received a copy of the GNU General Public License --
-- along with this library; if not, write to the Free Software Foundation, --
-- Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --
-- --
-- You are not allowed to use any part of this code to develop a program --
-- whose output would be used to harass or prosecute other users of the --
-- networks Adagio connects with. All data collected with Adagio or a tool --
-- containing Adagio code about other network users must remain --
-- confidential and cannot be made public by any mean, nor be used to --
-- harass or legally prosecute these users. --
------------------------------------------------------------------------------
-- $Id: dom-core-nodes-output.adb,v 1.3 2004/01/21 21:05:43 Jano Exp $
with Sax.Encodings; use Sax.Encodings;
package body Dom.Core.Nodes.Output is
----------
-- Sort --
----------
procedure Sort (Map : in out Named_Node_Map) is
Arr : Node_Array (0 .. Map.Last + 1) := (others => null);
Index : Natural;
begin
-- ??? The algorithm is not efficient, we use Insertion_Sort.
for J in 0 .. Map.Last loop
Index := 0;
loop
if Arr (Index) = null then
Arr (Index) := Map.Items (J);
exit;
end if;
if Node_Name (Map.Items (J)) <= Node_Name (Arr (Index)) then
Arr (Index + 1 .. Arr'Last) := Arr (Index .. Arr'Last - 1);
Arr (Index) := Map.Items (J);
exit;
end if;
Index := Index + 1;
end loop;
end loop;
for J in 0 .. Map.Last loop
Map.Items (J) := Arr (J);
end loop;
end Sort;
procedure Print
(N : Node;
U : in out ASU.Unbounded_string;
Print_Comments : Boolean := False;
Print_XML_PI : Boolean := False;
With_URI : Boolean := False) is
-- Print the contents of Node and its children in XML format.
-- If Print_Comments is True, then nodes associated with comments are
-- also displayed.
-- The <?xml?> processing instruction is displayed only if Print_XML_PI
-- By default, names are of the form ns_prefix:local_name. However, if
-- with_URI is True, names will be ns_URI:local_name instead
procedure Append (U : in out ASU.Unbounded_string; S : String)
renames ASU.Append;
procedure Print_Name (N : Node);
-- Print the name of the node.
----------------
-- Print_Name --
----------------
procedure Print_Name (N : Node) is
begin
if With_URI then
Append (U, Namespace_URI (N) & ':' & Local_Name (N));
else
Append (U, Node_Name (N));
end if;
end Print_Name;
begin
if N = null then
return;
end if;
case N.Node_Type is
when Element_Node =>
Append (U, "<");
Print_Name (N);
-- Sort the XML attributes as required for canonical XML
Sort (N.Attributes);
for J in 0 .. N.Attributes.Last loop
Append (U, " ");
Print (N.Attributes.Items (J), U,
Print_Comments, Print_XML_PI, With_URI);
end loop;
Append (U, ">");
Print (N.Children, U, Print_Comments, Print_XML_PI, With_URI);
Append (U, "</");
Print_Name (N);
Append (U, ">");
when Attribute_Node =>
Print_Name (N);
Append (U, "=""");
Append (U, Node_Value (N));
Append (U, """");
when Processing_Instruction_Node =>
if Print_XML_PI
or else N.Target.all /= Xml_Sequence
then
Append (U, "<?" & N.Target.all);
if N.Pi_Data'Length = 0
or else N.Pi_Data (N.Pi_Data'First) /= ' '
then
Append (U, " ");
end if;
Append (U, N.Pi_Data.all & "?>");
end if;
when Comment_Node =>
if Print_Comments then
Append (U, Node_Value (N));
end if;
when Document_Node =>
Print (N.Doc_Children, U,
Print_Comments, Print_XML_PI, With_URI);
when Document_Fragment_Node =>
Print (N.Doc_Frag_Children, U,
Print_Comments, Print_XML_PI, With_URI);
when Document_Type_Node | Notation_Node =>
null;
when Text_Node =>
Append (U, Node_Value (N));
when others =>
Append (U, Node_Value (N));
end case;
end Print;
procedure Print
(List : Dom.Core.Node_List;
U : in out ASU.Unbounded_string;
Print_Comments : Boolean := False;
Print_XML_PI : Boolean := False;
With_URI : Boolean := False) is
-- Same as Print, but for all the nodes in the list.
begin
for J in 0 .. List.Last loop
Print (List.Items (J), U, Print_Comments, Print_XML_PI, With_URI);
end loop;
end Print;
end Dom.Core.Nodes.Output;