SimpleXml : front-ends to read simple XML formats

Download simplexml.zip

Synopsis:

simplexmlattributesfacet.cs
simplexmlcommon.cs
simplexmlnodesfacet.cs
simplexmlparser.cs
simplexmlreader.cs
simplexmlreaderbase.cs
simplexmlreaderfacet.cs
simplexmlreader_test.cs
simplexmlsimplefacet.cs
simplexmlsimplreaderfacet.cs
simplexmlwithattributesreader.cs
simplexmlwithattributesreader_test.cs
simplexmlwithnodesreader.cs
simplexmlwithnodesreader_test.cs


simplexmlattributesfacet.cs

Synopsis
using System;
using System.IO;
using System.Collections;

namespace SimpleXml
{
  internal class AttributesFacet : ReaderFacet
  {
    private AttributeHandler mDefaultHandler = null;
    private Hashtable mCurrentAttributes = new Hashtable();

    public void AddHandler(string tag, AttributeHandler func)
    {
      mHandlerMap.Add(tag, func);
    }
    public void AddDefaultHandler(AttributeHandler func)
    {
      mDefaultHandler = func;
    }
    public override void OnStartElement()
    {
      mCurrentTag = mReader.Name;

      OnAttributes();
      OnEndElement();
    }
    public override void OnEndElement()
    {
      GetHandler() (mCurrentTag, mCurrentAttributes);
      mCurrentAttributes.Clear();
    }
    public override void OnTextElement()
    {
      throw new Exception(String.Format("The element must be empty. tag '{0}' at {1}", mCurrentTag, mReader.CurrentPosition));
    }
    public override void VerifyHandlers()
    {
      if (mHandlerMap.Count == 0 && mDefaultHandler == null)
        throw new Exception("A default handler or at least one handler is required.");
    }
    
    //------------ private from here on
    private AttributeHandler GetHandler()
    {
      if (mHandlerMap.ContainsKey(mCurrentTag))
        return (AttributeHandler) mHandlerMap[mCurrentTag];
      
      if (mDefaultHandler != null)
        return mDefaultHandler;
 
      throw new Exception(String.Format("No Handler specified for tag '{0}' at {1}", mCurrentTag, mReader.CurrentPosition));
    }
    private void OnAttributes()
    {
      if (!mReader.HasAttributes) return;

      while(mReader.MoveToNextAttribute())
        mCurrentAttributes[mReader.Name] = mReader.Value;
    }
  }
}

simplexmlcommon.cs

Synopsis
using System;
using System.Collections;

namespace SimpleXml
{
  public delegate void ElementHandler(string tag, string text);
  public delegate void AttributeHandler(string tag, Hashtable attributes);
}

simplexmlnodesfacet.cs

Synopsis
using System;
using System.IO;
using System.Collections;

namespace SimpleXml
{
  internal class NodesFacet : SimpleReaderFacet
  {
    private string mNodeTag = null;
    private bool mInNode;
    
    public string NodeTag
    {
      set { mNodeTag = value.ToLower().Trim(); }
    }
    public override void ResetAll()
    {
      mInNode = false;
      base.ResetAll();
    }
    public override void OnStartElement()
    {
      if (IsNodeElement())
      {
        mInNode = true;
        base.ResetAll();
        return;
      }
      
      CheckForMissingNode();
      base.OnStartElement();
    }
    public override void OnTextElement()
    {
      CheckForMissingNode();
      base.OnTextElement();
    }

    public override void OnEndElement()
    {
      if (IsNodeElement())
      {
        mInNode = false;
        return;
      }
      
      CheckForMissingNode();
      base.OnEndElement();
    }
    
    public override void VerifyConfig()
    {
      if (mNodeTag != null) return;
      throw new Exception("NodeTag has not been set.");
    }
    //------------- private from here on
    private void CheckForMissingNode()
    {
      if (mInNode) return;
      throw new Exception(String.Format("Missing <{0}> element at {1}.", mNodeTag, mReader.CurrentPosition));
    }
    private bool IsNodeElement()
    {
      return mReader.MatchesTag(mNodeTag);
    }
  }
}

simplexmlparser.cs

Synopsis
using System;
using System.IO;
using System.Xml;

namespace SimpleXml
{
  public class XmlParser 
  {
    XmlTextReader mReader;
    public XmlParser(Stream s)
    {
      mReader = new XmlTextReader(s);
    }
    public bool Read()
    {
      return mReader.Read();
    }
    public void Close()
    {
      mReader.Close();
    }
    public bool MatchesTag(string tag)
    {
      return Name.Equals(tag);
    }
    public bool IsEmptyElement
    {
      get { return  mReader.IsEmptyElement; }
    }
    public bool IsStartElement
    {
      get { return mReader.IsStartElement(); }
    }
    public bool IsEndElement
    {
      get {return mReader.NodeType == XmlNodeType.EndElement; }
    }
    public bool IsTextElement
    {
      get { return mReader.NodeType == XmlNodeType.Text; }
    }
    public bool IsIgnoredElement
    {
      get 
      {
        return mReader.NodeType == XmlNodeType.None ||
          mReader.NodeType == XmlNodeType.Whitespace ||
          mReader.NodeType == XmlNodeType.Comment;
      }
    }
    public string Name
    {
      get { return mReader.LocalName.ToLower().Trim(); }
    }
    public string CurrentPosition
    {
      get
      {
        return "line " + mReader.LineNumber  + ":" + mReader.LinePosition;
      }
    }
    public string NodeType
    {
      get { return   mReader.NodeType.ToString();}
    }
    public string Value
    {
      get { return mReader.Value; }
    }
    public bool HasAttributes
    {
      get { return mReader.HasAttributes; }
    }
    public bool MoveToNextAttribute()
    {
      return mReader.MoveToNextAttribute();
    }
  }
}

simplexmlreader.cs

Synopsis
using System;

namespace SimpleXml
{
  //handles xml files with a root tag and simple entries
  //  - no attributes
  //  - no mixed content
  //  - no nesting
  //example:
  // <ini>
  //   <tag1>element1</tag1>
  //   <tag2>element2</tag2>
  //   <tag3></tag3>
  //   <tag4 />
  // </ini>
  
  public class SimpleXmlReader : SimpleXmlReaderBase
  {
    private SimpleFacet mFacet = new SimpleFacet();

    public SimpleXmlReader()
    {
      Facet = mFacet;
    }
    public void Add(string tag, ElementHandler func)
    {
      mFacet.AddHandler(tag, func);
    }
    public void AddDefault(ElementHandler func)
    {
      mFacet.AddDefaultHandler(func);
    }
  }
}

simplexmlreaderbase.cs

Synopsis
using System;
using System.IO;
using System.Collections;

namespace SimpleXml
{
  //The implementation for most of the processing required
  //by the public classes
  public abstract class SimpleXmlReaderBase
  {
    private ReaderFacet mFacet = null;
    private XmlParser mReader = null;
    private string mRootTag = null;

    public string RootTag
    {
      set { mRootTag = value.ToLower().Trim(); }
    }
    public void load(string filename)
    {
      load(new FileStream(filename, FileMode.Open, FileAccess.Read));
    }
    public void load(Stream s)
    {
      mFacet.ResetAll();
      VerifyConfig();
      ParseStream(s);
    }
    //-------- private from here on
    internal ReaderFacet Facet
    {
      set { mFacet = value; }
    }
    private void VerifyConfig()
    {
      mFacet.VerifyConfig();
      if (mRootTag == null) 
        throw new Exception("RootTag has not been set.");
      mFacet.VerifyHandlers();
    }
    private void ParseStream(Stream s)
    {
      mReader = new XmlParser(s);
      mFacet.SetReader(mReader);
      while (mReader.Read())
        HandleElement();
      mReader.Close();     
    }
    private void HandleElement()
    {
      if (mReader.IsIgnoredElement) return;
      if (IsRootElement()) return;

      if (mReader.IsStartElement)
        mFacet.OnStartElement();
      else if (mReader.IsTextElement)
        mFacet.OnTextElement();
      else if (mReader.IsEndElement)
        mFacet.OnEndElement();
      else
        OnUnknownElement();
    }
    private void OnUnknownElement()
    {
      throw new Exception("Unknown Nodetype=" + mReader.NodeType + " found at " + mReader.CurrentPosition);
    }
    private bool IsRootElement()
    {
      return mReader.MatchesTag(mRootTag);
    }
  }
}

simplexmlreaderfacet.cs

Synopsis
using System;
using System.Collections;

namespace SimpleXml
{
  internal abstract class ReaderFacet
  {
    protected XmlParser mReader;
    protected string mCurrentTag = null;
    protected Hashtable mHandlerMap = new Hashtable();
  
    public void SetReader(XmlParser parser)
    {
      mReader = parser;
    }
    public virtual void ResetAll()
    {
      mCurrentTag = null;
    }
    public virtual void VerifyConfig()
    {
    }
    public abstract void OnStartElement();
    public abstract void OnTextElement();
    public abstract void OnEndElement();
    public abstract void VerifyHandlers();
  }
}

simplexmlreader_test.cs

Synopsis
using System;
using System.IO;
using System.Collections;
using SimpleXml;
using ut;

namespace SimpleXml.UnitTests
{
  /// <summary>
  /// Summary description for SimpleXmlReader_test.
  /// </summary>
  public class test_SimpleXmlReader
  {
    Hashtable mDict = new Hashtable();
    StreamWriter mWriter;
    private void textdelegate(string tag, string val)
    {
      mDict.Add(tag, val);
    }
    private void SetInputStream(string s)
    {
      mWriter = new StreamWriter(new MemoryStream());
      mWriter.Write(s);
      mWriter.Flush();
      mWriter.BaseStream.Position = 0;
    }
    public void test_empty()
    {
      mDict.Clear();
      SimpleXmlReader reader = new SimpleXmlReader();
      SetInputStream("<ini></ini>");
      reader.RootTag = "ini";
      reader.Add("entry", new ElementHandler(textdelegate));
      reader.load(mWriter.BaseStream);
      utx.assert(mDict.Count, 0);
    }
    public void test_singleentry()
    {
      mDict.Clear();
      SimpleXmlReader reader = new SimpleXmlReader();
      SetInputStream("<ini><entry>abc</entry></ini>");
      reader.RootTag = "ini";
      reader.Add("entry", new SimpleXml.ElementHandler(textdelegate));
      reader.load(mWriter.BaseStream);
      utx.assert(mDict.Count, 1);
      utx.assert(mDict["entry"], "abc");
    }
    public void test_singleentry_empty()
    {
      mDict.Clear();
      SimpleXmlReader reader = new SimpleXmlReader();
      SetInputStream("<ini><entry></entry></ini>");
      reader.RootTag = "ini";
      reader.Add("entry", new SimpleXml.ElementHandler(textdelegate));
      reader.load(mWriter.BaseStream);
      utx.assert(mDict.Count, 1);
      utx.assert(mDict["entry"], "");
    }
    public void test_singleentry_empty2()
    {
      mDict.Clear();
      SimpleXmlReader reader = new SimpleXmlReader();
      SetInputStream("<ini><entry /></ini>");
      reader.RootTag = "ini";
      reader.Add("entry", new SimpleXml.ElementHandler(textdelegate));
      reader.load(mWriter.BaseStream);
      utx.assert(mDict.Count, 1);
      utx.assert(mDict["entry"], "");
    }
    public void test_twoentries()
    {
      mDict.Clear();
      SimpleXmlReader reader = new SimpleXmlReader();
      SetInputStream("<ini><entry1>abc</entry1><entry2>def</entry2></ini>");
      reader.RootTag = "ini";
      reader.Add("entry1", new SimpleXml.ElementHandler(textdelegate));
      reader.Add("entry2", new SimpleXml.ElementHandler(textdelegate));
      reader.load(mWriter.BaseStream);
      utx.assert(mDict.Count, 2);
      utx.assert(mDict["entry1"], "abc");
      utx.assert(mDict["entry2"], "def");
    }
    public void test_whitespace()
    {
      mDict.Clear();
      SimpleXmlReader reader = new SimpleXmlReader();
      SetInputStream("<ini>" +Environment.NewLine+ "<entry1>abc</entry1><entry2>def</entry2></ini>");
      reader.RootTag = "ini";
      reader.Add("entry1", new SimpleXml.ElementHandler(textdelegate));
      reader.Add("entry2", new SimpleXml.ElementHandler(textdelegate));
      reader.load(mWriter.BaseStream);
      utx.assert(mDict.Count, 2);
      utx.assert(mDict["entry1"], "abc");
      utx.assert(mDict["entry2"], "def");
    }
    public void test_roottag_uppercase()
    {
      mDict.Clear();
      SimpleXmlReader reader = new SimpleXmlReader();
      SetInputStream("<ini>" +Environment.NewLine+ "<entry1>abc</entry1><entry2>def</entry2></ini>");
      reader.RootTag = " iNi ";
      reader.Add("entry1", new SimpleXml.ElementHandler(textdelegate));
      reader.Add("entry2", new SimpleXml.ElementHandler(textdelegate));
      reader.load(mWriter.BaseStream);
      utx.assert(mDict.Count, 2);
      utx.assert(mDict["entry1"], "abc");
      utx.assert(mDict["entry2"], "def");
    }
    public void test_unknowntag()
    {
      mDict.Clear();
      SimpleXmlReader reader = new SimpleXmlReader();
      SetInputStream("<ini><entryx>abc</entryx></ini>");
      reader.RootTag = " iNi ";
      reader.Add("entry", new SimpleXml.ElementHandler(textdelegate));
      try
      {
        reader.load(mWriter.BaseStream);
        utx.assert("excp not thrown", false);
      } 
      catch (Exception ex)
      {
        utx.assert(ex.Message, "No Handler specified for tag 'entryx' at line 1:19");
      }
    }
    public void test_parsefailure()
    {
      mDict.Clear();
      SimpleXmlReader reader = new SimpleXmlReader();
      SetInputStream("<ini><entry>abc</entry><ini>");
      reader.RootTag = " iNi ";
      reader.Add("entry", new SimpleXml.ElementHandler(textdelegate));
      try
      {
        reader.load(mWriter.BaseStream);
        utx.assert("excp not thrown", false);
      } 
      catch (Exception ex)
      {
        utx.assert(ex.Message, "This is an unexpected token. Expected 'EndElement'. Line 1, position 25.");
      }
    }
    public void test_parsefailure2()
    {
      mDict.Clear();
      SimpleXmlReader reader = new SimpleXmlReader();
      SetInputStream("<ini><entry>abc</entryx></ini>");
      reader.RootTag = " iNi ";
      reader.Add("entry", new SimpleXml.ElementHandler(textdelegate));
      try
      {
        reader.load(mWriter.BaseStream);
        utx.assert("excp not thrown", false);
      } 
      catch (Exception ex)
      {
        utx.assert(ex.Message, "The 'entry' start tag on line '1' does not match the end tag of 'entryx'. Line 1, position 18.");
      }
    }
    public void test_prereqfailure()
    {
      mDict.Clear();
      SimpleXmlReader reader = new SimpleXmlReader();
      SetInputStream("<ini><entry>abc</entry></ini>");
      try
      {
        reader.load(mWriter.BaseStream);
        utx.assert("excp not thrown", false);
      } 
      catch (Exception ex)
      {
        utx.assert(ex.Message, "RootTag has not been set.");
      }
    }
    public void test_prereqfailure2()
    {
      mDict.Clear();
      SimpleXmlReader reader = new SimpleXmlReader();
      SetInputStream("<ini><entry>abc</entry></ini>");
      try
      {
        reader.RootTag = " iNi ";
        reader.load(mWriter.BaseStream);
        utx.assert("excp not thrown", false);
      } 
      catch (Exception ex)
      {
        utx.assert(ex.Message, "A default handler or at least one handler is required.");
      }
    }
  }
}

simplexmlsimplefacet.cs

Synopsis
using System;

namespace SimpleXml
{
  internal class SimpleFacet : SimpleReaderFacet
  {
  }
}

simplexmlsimplreaderfacet.cs

Synopsis
using System;
using System.Collections;

namespace SimpleXml
{
  internal abstract class SimpleReaderFacet : ReaderFacet
  {
    protected ElementHandler mDefaultHandler = null;
    protected string mCurrentValue = null;    

    public void AddHandler(string tag, ElementHandler func)
    {
      mHandlerMap.Add(tag, func);
    }
    public void AddDefaultHandler(ElementHandler func)
    {
      mDefaultHandler = func;
    }
    public override void ResetAll()
    {
      mCurrentValue = "";
      base.ResetAll();
    }
    public override void OnStartElement()
    {
      mCurrentTag = mReader.Name;
      
      if (mReader.IsEmptyElement)
      {
        OnTextElement();
        OnEndElement();
      }
    }
    public override void OnTextElement()
    {
      mCurrentValue = mReader.Value;
    }
    public override void OnEndElement()
    {
      GetHandler() (mCurrentTag, mCurrentValue);
    }
    public override void VerifyHandlers()
    {
      if (mHandlerMap.Count == 0 && mDefaultHandler == null)
        throw new Exception("A default handler or at least one handler is required.");
    }

    //---------- protected from here on
    protected ElementHandler GetHandler()
    {
      if (mHandlerMap.ContainsKey(mCurrentTag))
        return (ElementHandler) mHandlerMap[mCurrentTag];
          
      if (mDefaultHandler != null)
        return mDefaultHandler;
     
      throw new Exception(String.Format("No Handler specified for tag '{0}' at {1}", mCurrentTag, mReader.CurrentPosition));
    }
  }
}

simplexmlwithattributesreader.cs

Synopsis
using System;
using System.IO;
using System.Collections;

namespace SimpleXml
{
  //handles xml files with a root tag and entries with attributes only
  //  - only attributes
  //  - no textvalue
  //  - no mixed content
  //  - no nesting
  //example:
  // <ini>
  //   <tag1 attr1="blah" attr2="blah" />
  //   <tag2 attr1="blah" attr2="blah" />
  //   <tag3 attr1="blah" attr2="blah" />
  // </ini>

  public class SimpleXmlWithAttributesReader : SimpleXmlReaderBase
  {
    private AttributesFacet mFacet = new AttributesFacet();
    public SimpleXmlWithAttributesReader()
    {
      Facet = mFacet;
    }
    public void Add(string tag, AttributeHandler func)
    {
      mFacet.AddHandler(tag, func);
    }
    public void AddDefault(AttributeHandler func)
    {
      mFacet.AddDefaultHandler(func);
    }

  }
}

simplexmlwithattributesreader_test.cs

Synopsis
using System;
using System.IO;
using System.Collections;
using SimpleXml;
using ut;

namespace SimpleXml.UnitTests
{
  /// <summary>
  /// Summary description for SimpleXmlWithAttributesReader_test.
  /// </summary>
  public class test_SimpleXmlWithAttributesReader
  {
    Hashtable mDict = new Hashtable();
    StreamWriter mWriter;
    private void textdelegate(string tag, Hashtable attrs)
    {
      foreach (DictionaryEntry entry in attrs)
      {
        try 
        {
          mDict.Add(tag + "." + (string) entry.Key, (string)entry.Value);
        } 
        catch (Exception )
        {
        }
      }
    }
    private void SetInputStream(string s)
    {
      mWriter = new StreamWriter(new MemoryStream());
      mWriter.Write(s);
      mWriter.Flush();
      mWriter.BaseStream.Position = 0;
    }
    // <ini>
    //   <tag1 attr1="blah" attr2="blah" />

    public void test_empty()
    {
      mDict.Clear();
      SimpleXmlWithAttributesReader reader = new SimpleXmlWithAttributesReader();
      SetInputStream("<ini></ini>");
      reader.RootTag = "ini";
      reader.Add("entry", new SimpleXml.AttributeHandler(textdelegate));
      reader.load(mWriter.BaseStream);
      utx.assert(mDict.Count, 0);
    }
    public void test_singleentry()
    {
      mDict.Clear();
      SimpleXmlWithAttributesReader reader = new SimpleXmlWithAttributesReader();
      SetInputStream("<ini><entry attr1='abc'/></ini>");
      reader.RootTag = "ini";
      reader.Add("entry", new SimpleXml.AttributeHandler(textdelegate));
      reader.load(mWriter.BaseStream);
      utx.assert(mDict.Count, 1);
      utx.assert(mDict["entry.attr1"], "abc");
    }
    public void test_singleentry2()
    {
      mDict.Clear();
      SimpleXmlWithAttributesReader reader = new SimpleXmlWithAttributesReader();
      SetInputStream("<ini><entry attr1='abc'></entry></ini>");
      reader.RootTag = "ini";
      reader.Add("entry", new SimpleXml.AttributeHandler(textdelegate));
      reader.load(mWriter.BaseStream);
      utx.assert(mDict.Count, 1);
      utx.assert(mDict["entry.attr1"], "abc");
    }
    public void test_singleentry_twoattrs()
    {
      mDict.Clear();
      SimpleXmlWithAttributesReader reader = new SimpleXmlWithAttributesReader();
      SetInputStream("<ini><entry attr1='abc' attr2='def'/></ini>");
      reader.RootTag = "ini";
      reader.Add("entry", new SimpleXml.AttributeHandler(textdelegate));
      reader.load(mWriter.BaseStream);
      utx.assert(mDict.Count, 2);
      utx.assert(mDict["entry.attr1"], "abc");
      utx.assert(mDict["entry.attr2"], "def");
    }
    public void test_singleentry_zeroattrs()
    {
      mDict.Clear();
      SimpleXmlWithAttributesReader reader = new SimpleXmlWithAttributesReader();
      SetInputStream("<ini><entry /></ini>");
      reader.RootTag = "ini";
      reader.Add("entry", new SimpleXml.AttributeHandler(textdelegate));
      reader.load(mWriter.BaseStream);
      utx.assert(mDict.Count, 0);
    }
    public void test_twoentries_twoattrs()
    {
      mDict.Clear();
      SimpleXmlWithAttributesReader reader = new SimpleXmlWithAttributesReader();
      SetInputStream("<ini><entry1 attr1='abc' attr2='def'/><entry2 attr1='abc' attr2='def'/></ini>");
      reader.RootTag = "ini";
      reader.Add("entry1", new SimpleXml.AttributeHandler(textdelegate));
      reader.Add("entry2", new SimpleXml.AttributeHandler(textdelegate));
      reader.load(mWriter.BaseStream);
      utx.assert(mDict.Count, 4);
      utx.assert(mDict["entry1.attr1"], "abc");
      utx.assert(mDict["entry1.attr2"], "def");
      utx.assert(mDict["entry2.attr1"], "abc");
      utx.assert(mDict["entry2.attr2"], "def");
    }
    public void test_usedefaulthandler()
    {
      mDict.Clear();
      SimpleXmlWithAttributesReader reader = new SimpleXmlWithAttributesReader();
      SetInputStream("<ini><entry1 attr1='abc' attr2='def'/><entry2 attr1='abc' attr2='def'/></ini>");
      reader.RootTag = "ini";
      reader.AddDefault(new SimpleXml.AttributeHandler(textdelegate));
      reader.load(mWriter.BaseStream);
      utx.assert(mDict.Count, 4);
      utx.assert(mDict["entry1.attr1"], "abc");
      utx.assert(mDict["entry1.attr2"], "def");
      utx.assert(mDict["entry2.attr1"], "abc");
      utx.assert(mDict["entry2.attr2"], "def");
    }
    public void test_whitespace()
    {
      mDict.Clear();
      SimpleXmlWithAttributesReader reader = new SimpleXmlWithAttributesReader();
      SetInputStream("<ini>"+Environment.NewLine+"<entry attr1='abc'/></ini>");
      reader.RootTag = " iNi ";
      reader.Add("entry", new SimpleXml.AttributeHandler(textdelegate));
      reader.load(mWriter.BaseStream);
      utx.assert(mDict.Count, 1);
      utx.assert(mDict["entry.attr1"], "abc");
    }
    public void test_roottag_uppercase()
    {
      mDict.Clear();
      SimpleXmlWithAttributesReader reader = new SimpleXmlWithAttributesReader();
      SetInputStream("<ini><entry attr1='abc'/></ini>");
      reader.RootTag = " iNi ";
      reader.Add("entry", new SimpleXml.AttributeHandler(textdelegate));
      reader.load(mWriter.BaseStream);
      utx.assert(mDict.Count, 1);
      utx.assert(mDict["entry.attr1"], "abc");
    }
    public void test_elementisnotempty()
    {
      mDict.Clear();
      SimpleXmlWithAttributesReader reader = new SimpleXmlWithAttributesReader();
      SetInputStream("<ini><entry attr1='abc'>blah</entry></ini>");
      reader.RootTag = "ini";
      reader.Add("entry", new SimpleXml.AttributeHandler(textdelegate));
      try
      {
        reader.load(mWriter.BaseStream);
        utx.assert("excp not thrown", false);
      } 
      catch (Exception ex)
      {
        utx.assert(ex.Message, "The element must be empty. tag 'entry' at line 1:25");
      }
    }
    public void test_unknowntag()
    {
      mDict.Clear();
      SimpleXmlWithAttributesReader reader = new SimpleXmlWithAttributesReader();
      SetInputStream("<ini><entryx attr1='abc'/></ini>");
      reader.RootTag = " iNi ";
      reader.Add("entry", new SimpleXml.AttributeHandler(textdelegate));
      try
      {
        reader.load(mWriter.BaseStream);
        utx.assert("excp not thrown", false);
      } 
      catch (Exception ex)
      {
        utx.assert(ex.Message, "No Handler specified for tag 'entryx' at line 1:14");
      }
    }
    public void test_parsefailure()
    {
      mDict.Clear();
      SimpleXmlWithAttributesReader reader = new SimpleXmlWithAttributesReader();
      SetInputStream("<ini><entry attr1='abc'/><ini>");
      reader.RootTag = " iNi ";
      reader.Add("entry", new SimpleXml.AttributeHandler(textdelegate));
      try
      {
        reader.load(mWriter.BaseStream);
        utx.assert("excp not thrown", false);
      } 
      catch (Exception ex)
      {
        utx.assert(ex.Message, "This is an unexpected token. Expected 'EndElement'. Line 1, position 27.");
      }
    }
    public void test_parsefailure2()
    {
      mDict.Clear();
      SimpleXmlWithAttributesReader reader = new SimpleXmlWithAttributesReader();
      SetInputStream("<ini><entry attr1='abc'></ini>");
      reader.RootTag = " iNi ";
      reader.Add("entry", new SimpleXml.AttributeHandler(textdelegate));
      try
      {
        reader.load(mWriter.BaseStream);
        utx.assert("excp not thrown", false);
      } 
      catch (Exception ex)
      {
        utx.assert(ex.Message, "The 'entry' start tag on line '1' does not match the end tag of 'ini'. Line 1, position 27.");
      }
    }
    public void test_prereqfailure()
    {
      mDict.Clear();
      SimpleXmlWithAttributesReader reader = new SimpleXmlWithAttributesReader();
      SetInputStream("<ini><entry attr1='abc' /></ini>");
      try
      {
        reader.load(mWriter.BaseStream);
        utx.assert("excp not thrown", false);
      } 
      catch (Exception ex)
      {
        utx.assert(ex.Message, "RootTag has not been set.");
      }
    }
    public void test_prereqfailure2()
    {
      mDict.Clear();
      SimpleXmlWithAttributesReader reader = new SimpleXmlWithAttributesReader();
      SetInputStream("<ini><entry attr1='abc' /></ini>");
      try
      {
        reader.RootTag = " iNi ";
        reader.load(mWriter.BaseStream);
        utx.assert("excp not thrown", false);
      } 
      catch (Exception ex)
      {
        utx.assert(ex.Message, "A default handler or at least one handler is required.");
      }
    }
    //public void test_withfile()
    //{
    //  mDict.Clear();
    //  SimpleXmlWithAttributesReader reader = new SimpleXmlWithAttributesReader();
    //  reader.RootTag = "config";
    //  reader.AddDefault(new SimpleXml.AttributeHandler(textdelegate));
    //  reader.load(@"D:\projects\src\SimpleXml\utest.xml");
    //  utx.assert(mDict.Count, 5);
    //  //utx.assert(mDict["entry.attr1"], "abc");
    //}
  }
}

simplexmlwithnodesreader.cs

Synopsis
using System;

namespace SimpleXml
{
  //handles xml files with a root tag and simple repeating node entries
  //  - no attributes
  //  - no mixed content
  //  - no nesting
  //example:
  // <ini>
  //   <node>
  //     <tag1>element1</tag1>
  //     <tag2>element2</tag2>
  //   </node>
  //   <node>
  //     <tag1>element3</tag1>
  //     <tag2>element4</tag2>
  //   </node>
  // </ini>
  public class SimpleXmlWithNodesReader : SimpleXmlReaderBase
  {
    private NodesFacet mFacet = new NodesFacet();

    public SimpleXmlWithNodesReader()
    {
      Facet = mFacet;
    }
    public void Add(string tag, ElementHandler func)
    {
      mFacet.AddHandler(tag, func);
    }
    public void AddDefault(ElementHandler func)
    {
      mFacet.AddDefaultHandler(func);
    }
    public string NodeTag
    {
      set { mFacet.NodeTag = value; }
    }
  }
}

simplexmlwithnodesreader_test.cs

Synopsis
using System;
using System.IO;
using System.Collections;
using SimpleXml;
using ut;

namespace SimpleXml.UnitTests
{
  /// <summary>
  /// Summary description for SimpleXmlWithNodesReader_test.
  /// </summary>
  public class test_SimpleXmlWithNodesReader
  {
    Hashtable mDict = new Hashtable();
    StreamWriter mWriter;
    private void textdelegate(string tag, string val)
    {
      mDict.Add(tag, val);
    }
    private void SetInputStream(string s)
    {
      mWriter = new StreamWriter(new MemoryStream());
      mWriter.Write(s);
      mWriter.Flush();
      mWriter.BaseStream.Position = 0;
    }
    public void test_empty()
    {
      mDict.Clear();
      SimpleXmlWithNodesReader reader = new SimpleXmlWithNodesReader();
      SetInputStream("<ini></ini>");
      reader.RootTag = "ini";
      reader.NodeTag = "node";
      reader.Add("entry", new SimpleXml.ElementHandler(textdelegate));
      reader.load(mWriter.BaseStream);
      utx.assert(mDict.Count, 0);
    }
    public void test_singleentry()
    {
      mDict.Clear();
      SimpleXmlWithNodesReader reader = new SimpleXmlWithNodesReader();
      SetInputStream("<ini><node><entry>abc</entry></node></ini>");
      reader.RootTag = "ini";
      reader.NodeTag = "node";
      reader.Add("entry", new SimpleXml.ElementHandler(textdelegate));
      reader.load(mWriter.BaseStream);
      utx.assert(mDict.Count, 1);
      utx.assert(mDict["entry"], "abc");
    }
    public void test_singleentry_empty()
    {
      mDict.Clear();
      SimpleXmlWithNodesReader reader = new SimpleXmlWithNodesReader();
      SetInputStream("<ini><node><entry></entry></node></ini>");
      reader.RootTag = "ini";
      reader.NodeTag = "node";
      reader.Add("entry", new SimpleXml.ElementHandler(textdelegate));
      reader.load(mWriter.BaseStream);
      utx.assert(mDict.Count, 1);
      utx.assert(mDict["entry"], "");
    }
    public void test_singleentry_empty2()
    {
      mDict.Clear();
      SimpleXmlWithNodesReader reader = new SimpleXmlWithNodesReader();
      SetInputStream("<ini><node><entry /></node></ini>");
      reader.RootTag = "ini";
      reader.NodeTag = "node";
      reader.Add("entry", new SimpleXml.ElementHandler(textdelegate));
      reader.load(mWriter.BaseStream);
      utx.assert(mDict.Count, 1);
      utx.assert(mDict["entry"], "");
    }
    public void test_missingnode()
    {
      mDict.Clear();
      SimpleXmlWithNodesReader reader = new SimpleXmlWithNodesReader();
      SetInputStream("<ini><entry></entry></ini>");
      reader.RootTag = "ini";
      reader.NodeTag = "node";
      reader.Add("entry", new SimpleXml.ElementHandler(textdelegate));
      try
      {
        reader.load(mWriter.BaseStream);
        utx.assert("excp not thrown", false);
      } 
      catch (Exception ex)
      {
        utx.assert(ex.Message, "Missing <node> element at line 1:7.");
      }
    }
    public void test_missingnode2()
    {
      mDict.Clear();
      SimpleXmlWithNodesReader reader = new SimpleXmlWithNodesReader();
      SetInputStream("<ini><node><entry1>abc</entry1></node><entry2 /><node><entry3>def</entry3></node></ini>");
      reader.RootTag = "ini";
      reader.NodeTag = "node";
      reader.AddDefault(new SimpleXml.ElementHandler(textdelegate));
      try
      {
        reader.load(mWriter.BaseStream);
        utx.assert("excp not thrown", false);
      } 
      catch (Exception ex)
      {
        utx.assert(ex.Message, "Missing <node> element at line 1:40.");
      }
    }
    public void test_twoentries()
    {
      mDict.Clear();
      SimpleXmlWithNodesReader reader = new SimpleXmlWithNodesReader();
      SetInputStream("<ini><node><entry1>abc</entry1><entry2>def</entry2></node></ini>");
      reader.RootTag = "ini";
      reader.NodeTag = "node";
      reader.Add("entry1", new SimpleXml.ElementHandler(textdelegate));
      reader.Add("entry2", new SimpleXml.ElementHandler(textdelegate));
      reader.load(mWriter.BaseStream);
      utx.assert(mDict.Count, 2);
      utx.assert(mDict["entry1"], "abc");
      utx.assert(mDict["entry2"], "def");
    }
    public void test_twonodes()
    {
      mDict.Clear();
      SimpleXmlWithNodesReader reader = new SimpleXmlWithNodesReader();
      SetInputStream("<ini><node><entry1>abc</entry1></node><node><entry2>def</entry2></node></ini>");
      reader.RootTag = "ini";
      reader.NodeTag = "node";
      reader.Add("entry1", new SimpleXml.ElementHandler(textdelegate));
      reader.Add("entry2", new SimpleXml.ElementHandler(textdelegate));
      reader.load(mWriter.BaseStream);
      utx.assert(mDict.Count, 2);
      utx.assert(mDict["entry1"], "abc");
      utx.assert(mDict["entry2"], "def");
    }
    public void test_whitespace()
    {
      mDict.Clear();
      SimpleXmlWithNodesReader reader = new SimpleXmlWithNodesReader();
      SetInputStream("<ini>" +Environment.NewLine+ "<node><entry1>abc</entry1><entry2>def</entry2></node></ini>");
      reader.RootTag = "ini";
      reader.NodeTag = "node";
      reader.Add("entry1", new SimpleXml.ElementHandler(textdelegate));
      reader.Add("entry2", new SimpleXml.ElementHandler(textdelegate));
      reader.load(mWriter.BaseStream);
      utx.assert(mDict.Count, 2);
      utx.assert(mDict["entry1"], "abc");
      utx.assert(mDict["entry2"], "def");
    }
    public void test_roottag_uppercase()
    {
      mDict.Clear();
      SimpleXmlWithNodesReader reader = new SimpleXmlWithNodesReader();
      SetInputStream("<ini>" +Environment.NewLine+ "<node><entry1>abc</entry1><entry2>def</entry2></node></ini>");
      reader.RootTag = " iNi ";
      reader.NodeTag = "node";
      reader.Add("entry1", new SimpleXml.ElementHandler(textdelegate));
      reader.Add("entry2", new SimpleXml.ElementHandler(textdelegate));
      reader.load(mWriter.BaseStream);
      utx.assert(mDict.Count, 2);
      utx.assert(mDict["entry1"], "abc");
      utx.assert(mDict["entry2"], "def");
    }
    public void test_nodetag_uppercase()
    {
      mDict.Clear();
      SimpleXmlWithNodesReader reader = new SimpleXmlWithNodesReader();
      SetInputStream("<ini>" +Environment.NewLine+ "<node><entry1>abc</entry1><entry2>def</entry2></node></ini>");
      reader.RootTag = " iNi ";
      reader.NodeTag = "  nOdE ";
      reader.Add("entry1", new SimpleXml.ElementHandler(textdelegate));
      reader.Add("entry2", new SimpleXml.ElementHandler(textdelegate));
      reader.load(mWriter.BaseStream);
      utx.assert(mDict.Count, 2);
      utx.assert(mDict["entry1"], "abc");
      utx.assert(mDict["entry2"], "def");
    }
    public void test_unknowntag()
    {
      mDict.Clear();
      SimpleXmlWithNodesReader reader = new SimpleXmlWithNodesReader();
      SetInputStream("<ini><node><entryx>abc</entryx></node></ini>");
      reader.RootTag = " iNi ";
      reader.NodeTag = "node";
      reader.Add("entry", new SimpleXml.ElementHandler(textdelegate));
      try
      {
        reader.load(mWriter.BaseStream);
        utx.assert("excp not thrown", false);
      } 
      catch (Exception ex)
      {
        utx.assert(ex.Message, "No Handler specified for tag 'entryx' at line 1:25");
      }
    }
    public void test_parsefailure()
    {
      mDict.Clear();
      SimpleXmlWithNodesReader reader = new SimpleXmlWithNodesReader();
      SetInputStream("<ini><node><entry>abc</entry></node><ini>");
      reader.RootTag = " iNi ";
      reader.NodeTag = "node";
      reader.Add("entry", new SimpleXml.ElementHandler(textdelegate));
      try
      {
        reader.load(mWriter.BaseStream);
        utx.assert("excp not thrown", false);
      } 
      catch (Exception ex)
      {
        utx.assert(ex.Message, "This is an unexpected token. Expected 'EndElement'. Line 1, position 38.");
      }
    }
    public void test_parsefailure2()
    {
      mDict.Clear();
      SimpleXmlWithNodesReader reader = new SimpleXmlWithNodesReader();
      SetInputStream("<ini><node><entry>abc</entryx></node></ini>");
      reader.RootTag = " iNi ";
      reader.NodeTag = "node";
      reader.Add("entry", new SimpleXml.ElementHandler(textdelegate));
      try
      {
        reader.load(mWriter.BaseStream);
        utx.assert("excp not thrown", false);
      } 
      catch (Exception ex)
      {
        utx.assert(ex.Message, "The 'entry' start tag on line '1' does not match the end tag of 'entryx'. Line 1, position 24.");
      }
    }
    public void test_prereqfailure()
    {
      mDict.Clear();
      SimpleXmlWithNodesReader reader = new SimpleXmlWithNodesReader();
      SetInputStream("<ini><entry>abc</entry></ini>");
      try
      {
        reader.NodeTag = "node";
        reader.load(mWriter.BaseStream);
        utx.assert("excp not thrown", false);
      } 
      catch (Exception ex)
      {
        utx.assert(ex.Message, "RootTag has not been set.");
      }
    }
    public void test_prereqfailure2()
    {
      mDict.Clear();
      SimpleXmlWithNodesReader reader = new SimpleXmlWithNodesReader();
      SetInputStream("<ini><entry>abc</entry></ini>");
      try
      {
        reader.RootTag = " iNi ";
        reader.NodeTag = "node";
        reader.load(mWriter.BaseStream);
        utx.assert("excp not thrown", false);
      } 
      catch (Exception ex)
      {
        utx.assert(ex.Message, "A default handler or at least one handler is required.");
      }
    }
    public void test_prereqfailure3()
    {
      mDict.Clear();
      SimpleXmlWithNodesReader reader = new SimpleXmlWithNodesReader();
      SetInputStream("<ini><entry>abc</entry></ini>");
      try
      {
        reader.RootTag = " iNi ";
        reader.load(mWriter.BaseStream);
        utx.assert("excp not thrown", false);
      } 
      catch (Exception ex)
      {
        utx.assert(ex.Message, "NodeTag has not been set.");
      }
    }
  }
}






Contact me about content on this page using john_web-at-arrizza-dot-com
For Web Master or site problems contact: webadmin-at-arrizza-dot-com
Copyright John Arrizza (c) 2001-2010