none
Trying to write a simple program to gather strings, and save in xml file RRS feed

  • Question

  • Hello Everyone, I am trying to write a layer gathering and changing program for AutoCAD that will store a lists of layers based on layers they need to be changed to. I am writing it in C# and the part that is killing me is I need to store the old layers before I convert them so that way in the future the program will automatically know to change those layers to the appropriate layer.

     

    I am trying to use an .xml file to permanently store the layers, and a serializer to read the layers into a dictionary so that I can search and see if I have already come across a layer.

     

    I know that sounds very convoluted so let me simplify the problem. For those of you not familiar with AutoCAD the layers are just strings. We have our layers which are only 7 layers. We get drawings from outside sources and they have their layers. Their layers correspond to one of our 7 layers. We have a list showing which of their layers correspond to one of our layers. When we get drawings with layers we've never seen before, we need to search through the list to confirm it isn't already there and if it is not present, then ask the user to which of our layers their new layer should be associated.

     

    I want to store the data in a xml file in a manner similar to this

     

    <ourlayertheirlayer>
      ourlayer1, somerandomthintg
      ourlayer1, anotherrandomthing
      ourlayer1, thisrandomthing
      ourlayer2, whatisthis
      ourlayer2, whoisthis
      ourlayer3, whycantifigurethisout
      ourlayer3, canyoufigureitout
    </ourlayertheirlayer>

     Then I want to serialize the xml file and save the data in a Dictionary<string,string> type where the first string is one of our layers and the second string is their layer.

     

    I want the data in the xml file to persist between application sessions, but the dictionary would be filled each time the program is started.

     

    Later in the program I will use the Dictionary to gather all the objects based on their layer, the second string in the dictionary, and convert them to our corresponding layer, the first string in the dictionary.

     

    I am having trouble setting up my types in C# though. How do I create an xml serializer that will read ourlayer, theirlayer from an xml file and save it to a Dictionary. The data doesn't have to be in the xml file in that format either, I just can't think of an easier way than commas to sepearte the two pieces of data. I just need them to stay separate so that I can compare new strings to the second set of strings and later use the first set of strings, our layers to convert the second set of strings, their layers to whichever of our layers it was associated.

     

    I was thinking something like this.

     

    public class OursTheirs
    {
      public List<string>[,] goToDict { get; set; }
    }
    
    public class oursTheirsComma
    {
      public string commaPresent { get; set; }
    }
    
    public static class SerializeAddToDict
    {
      public static string getFromXML(string xml)
      {
        XmlSerializer xmls = new XMLSerializer(typeof(string));
        return xmls.Deserialize(new StringReader(xml)) as string;
      }
      public static List<string>[,] ParseXML
      {
      //Stuff here I haven't figured out to convert the string to a
      //List<string>[,] where the first column is one of our 7 layers,second
      //column their layer
      }
    
      //Then some other stuff here to create and fill the Dictionary
    }

     I just starting learning C# and .NET about 2 weeks ago so please forgive any obvious errors or incorrect casing.

    Friday, August 2, 2013 7:48 PM

Answers

  • I was going to suggest serializing your Dictionary with the XmlSerializer, but guess what ... a Dictionary cannot be serialized that way. But, that's ok because there is something called the DataContractSerializer which will work just fine. Here a few code snippets to get you going with this:

    First, let's get some test data loaded into your Dictionary:

    Dictionary<string, List<string>> Layers = new Dictionary<string, List<string>>();
    Layers.Add("ourlayer1", new List<string>());
    Layers["ourlayer1"].Add("somerandomthing");
    Layers["ourlayer1"].Add("anotherrandomthing");
    
    Layers.Add("ourlayer2", new List<string>());
    Layers["ourlayer2"].Add("whatisthis");
    Layers["ourlayer2"].Add("whoisthis");
    

    Next, serialize and write it out to an XML file:

    DataContractSerializer dc = new DataContractSerializer(typeof(Dictionary<string, List<string>>));
    
    using (StringWriter sw = new StringWriter())
    using (var writer = new XmlTextWriter(sw))
    {
    	writer.Formatting = Formatting.Indented; // indent the Xml so it's human readable
    	dc.WriteObject(writer, Layers);
    	writer.Flush();
    	File.WriteAllText("Layers.xml", sw.ToString());
    }
    

    And, last but not least, let's read the file back into a Dictionary:

    string s = File.ReadAllText("Layers.xml");
    using (StreamReader sr = new StreamReader("Layers.xml"))
    {
    	Layers = dc.ReadObject(sr.BaseStream) as Dictionary<string, List<string>>;
    }
    

    I've tried this out and it works perfectly, so if you have any problems with it, let me know.


    ~~Bonnie Berent DeWitt [C# MVP]

    http://geek-goddess-bonnie.blogspot.com

    Monday, August 5, 2013 1:14 AM
    Moderator

All replies

  • I was going to suggest serializing your Dictionary with the XmlSerializer, but guess what ... a Dictionary cannot be serialized that way. But, that's ok because there is something called the DataContractSerializer which will work just fine. Here a few code snippets to get you going with this:

    First, let's get some test data loaded into your Dictionary:

    Dictionary<string, List<string>> Layers = new Dictionary<string, List<string>>();
    Layers.Add("ourlayer1", new List<string>());
    Layers["ourlayer1"].Add("somerandomthing");
    Layers["ourlayer1"].Add("anotherrandomthing");
    
    Layers.Add("ourlayer2", new List<string>());
    Layers["ourlayer2"].Add("whatisthis");
    Layers["ourlayer2"].Add("whoisthis");
    

    Next, serialize and write it out to an XML file:

    DataContractSerializer dc = new DataContractSerializer(typeof(Dictionary<string, List<string>>));
    
    using (StringWriter sw = new StringWriter())
    using (var writer = new XmlTextWriter(sw))
    {
    	writer.Formatting = Formatting.Indented; // indent the Xml so it's human readable
    	dc.WriteObject(writer, Layers);
    	writer.Flush();
    	File.WriteAllText("Layers.xml", sw.ToString());
    }
    

    And, last but not least, let's read the file back into a Dictionary:

    string s = File.ReadAllText("Layers.xml");
    using (StreamReader sr = new StreamReader("Layers.xml"))
    {
    	Layers = dc.ReadObject(sr.BaseStream) as Dictionary<string, List<string>>;
    }
    

    I've tried this out and it works perfectly, so if you have any problems with it, let me know.


    ~~Bonnie Berent DeWitt [C# MVP]

    http://geek-goddess-bonnie.blogspot.com

    Monday, August 5, 2013 1:14 AM
    Moderator
  • Thank you Bonnie. I am going to try this. Assuming I can get Autodesk.AutoCAD.DatabaseServices.Database.ReadDwgFile(string, Autodesk.AutoCAD.DatabaseServices.FileOpenMode, bool, string) to work. I'm not sure why, but there are three different ReadDwgFile methods and no matter which one I choose, I get an error.
    Tuesday, August 6, 2013 12:12 PM
  • I'm afraid I can't help you with that one . I assume that Autodesk must have some kind of forums where you can get some help (yes, there is a forum ... I just Googled Autodesk.AutoCAD.DatabaseServices.Database.ReadDwgFile and found their forum). So, good luck with that and once you solve that issue, let me know if my Dictionary serialization suggestion is useful or not.

    ~~Bonnie Berent DeWitt [C# MVP]

    http://geek-goddess-bonnie.blogspot.com

    Tuesday, August 6, 2013 3:18 PM
    Moderator