/* * Copyright (c) 2004 The University of Wroclaw. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the University may not be used to endorse or promote * products derived from this software without specific prior * written permission. * * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN * NO EVENT SHALL THE UNIVERSITY BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ namespace Nemerle.Xml { using System.Xml; using Nemerle.Collections; /** * An XML document with easy node identifiation. */ public class XmlTemplate { /** * Creates an XmlTemplate basing on an XmlDocument */ public this (document : XmlDocument) { this.document = document; this.nodes_by_id = Hashtable (200); fill_nodes_by_id () } /** * Reads an XML document from a file and fills the IDs */ public this (filename : string) { this.document = XmlDocument (); def reader = XmlTextReader (filename); reader.XmlResolver = null; this.document.Load (reader); this.nodes_by_id = Hashtable (200); fill_nodes_by_id () } /* -- PUBLIC METHODS ----------------------------------------------------- */ /** * Returns a node given it's ID */ public NodeById (id : string) : XmlElement { match (nodes_by_id.Get (id)) { | None => throw System.ArgumentException ("id " + id + " not present") | Some (old) => old } } /** * Put specified [text] as the only content of node [id]. * Return the document with this change performed. */ public SetText (id : string, text : string) : void { def slash_pos = id.IndexOf ('/'); if (slash_pos != -1) { def node = NodeById (id.Substring (0, slash_pos)); def attr_name = id.Substring (slash_pos + 1); node.SetAttribute (attr_name, text) } else { def node = NodeById (id); // shoot out all children while (node.FirstChild != null) ignore (node.RemoveChild (node.FirstChild)); ignore (node.PrependChild (document.CreateTextNode (text))); } } /** * Returns the XML document associated with this object */ public GetDocument () : XmlDocument { document } /* -- PRIVATE METHODS -------------------------------------------------- */ /** * Creates the nodes ID lookup table */ fill_nodes_by_id () : void { def walk (n : XmlNode) { when (n.NodeType == XmlNodeType.Element) { def elt = (n :> XmlElement); def attr = elt.GetAttribute ("id"); def attr = if (attr == "") elt.GetAttribute ("name") else attr; when (attr != "" && !nodes_by_id.Contains (attr)) nodes_by_id.Add (attr, elt); }; def walk_children (cur : XmlNode) { if (cur == null) () else { walk (cur); walk_children (cur.NextSibling); } }; walk_children (n.FirstChild) }; walk (document) } /* -- PRIVATE FIELDS --------------------------------------------------- */ document : XmlDocument; nodes_by_id : Hashtable [string, XmlElement]; } }