Using System.Reflection to walk values in an array???
-
I have an object that is several levels deep. It may or may not contain values in each level. I need to serialize the object as XML -- and yes, I would normally use XmlSerializer to accomplish this. The problem is that the application this is feeding requires an XML format that is not well-formed. The area in which it loses it's well-formedness (is that a word) is with arrays. That is also the area I'm having troubles getting my hands around. I have my primary code which handles the parent and then creates instances of ObjectWalker and IEnumerableWalker to handle flat objects and arrays. Furthermore the arrays are only System.Collection.ArrayList. So I can specifically state that if
property.DeclaringType.Name.Equals("ArrayList")
then I know I have an array. What I'd like to do is get the actual array object and pass it to my IEnumerableWalker, but it seems I cannot do that. So I'm passing the PropertyInfo of the ArrayList, the object it is contained in, and the current Xml depth. What I cannot find on the internet or here is the next step of iterating through each element in the array and getting the property names and values. If anyone can point me to a good article or snippet that does this I'd appreciate it! Thanks Here is my ObjectWalker that eventually calls an instance of IEnumerableWalker:public void Walk(object newHierarchy, int depth) { Type objectType = newHierarchy.GetType(); XmlWriter.WriteOpen(objectType.Name); PropertyInfo\[\] properties = objectType.GetProperties(); foreach (PropertyInfo property in properties) { Trace.WriteLine("Processing property" + property.Name); if (property.DeclaringType.Name.Equals("ArrayList")) { new IEnumerableWalker().Walk(property, newHierarchy, depth); } else if (property.PropertyType.FullName.StartsWith("MyNamespace")) { object itemValue = property.GetValue(newHierarchy, null); new ObjectWalker().Walk(itemValue, depth+1); } else if (property.CanRead && property.CanWrite && property.GetValue(newHierarchy, null) != null ) { XmlWriter.WriteLine(property.Name, property.GetValue(newHierarchy, null).ToString(), depth); } } XmlWriter.WriteClose(objectType.Name
-
I have an object that is several levels deep. It may or may not contain values in each level. I need to serialize the object as XML -- and yes, I would normally use XmlSerializer to accomplish this. The problem is that the application this is feeding requires an XML format that is not well-formed. The area in which it loses it's well-formedness (is that a word) is with arrays. That is also the area I'm having troubles getting my hands around. I have my primary code which handles the parent and then creates instances of ObjectWalker and IEnumerableWalker to handle flat objects and arrays. Furthermore the arrays are only System.Collection.ArrayList. So I can specifically state that if
property.DeclaringType.Name.Equals("ArrayList")
then I know I have an array. What I'd like to do is get the actual array object and pass it to my IEnumerableWalker, but it seems I cannot do that. So I'm passing the PropertyInfo of the ArrayList, the object it is contained in, and the current Xml depth. What I cannot find on the internet or here is the next step of iterating through each element in the array and getting the property names and values. If anyone can point me to a good article or snippet that does this I'd appreciate it! Thanks Here is my ObjectWalker that eventually calls an instance of IEnumerableWalker:public void Walk(object newHierarchy, int depth) { Type objectType = newHierarchy.GetType(); XmlWriter.WriteOpen(objectType.Name); PropertyInfo\[\] properties = objectType.GetProperties(); foreach (PropertyInfo property in properties) { Trace.WriteLine("Processing property" + property.Name); if (property.DeclaringType.Name.Equals("ArrayList")) { new IEnumerableWalker().Walk(property, newHierarchy, depth); } else if (property.PropertyType.FullName.StartsWith("MyNamespace")) { object itemValue = property.GetValue(newHierarchy, null); new ObjectWalker().Walk(itemValue, depth+1); } else if (property.CanRead && property.CanWrite && property.GetValue(newHierarchy, null) != null ) { XmlWriter.WriteLine(property.Name, property.GetValue(newHierarchy, null).ToString(), depth); } } XmlWriter.WriteClose(objectType.Name
i'm not sure if i got what you want. for now, it seems as if you need to replace
new IEnumerableWalker().Walk(property, newHierarchy, depth);
with something likeforeach (object val in ((ArrayList)property.GetValue(newHierarchy, null)).Items) { Walk(val, depth); }
..or did i get you wrong? -
i'm not sure if i got what you want. for now, it seems as if you need to replace
new IEnumerableWalker().Walk(property, newHierarchy, depth);
with something likeforeach (object val in ((ArrayList)property.GetValue(newHierarchy, null)).Items) { Walk(val, depth); }
..or did i get you wrong?Almost. But you helped me realize I'm closer than I thought. Seems my base object being passed to the ObjectWalker IS the array list. So I have to step through and find out why it isn't going to the IEnumerableWalker. I have the enumerable walker there because this is where the well-formed xml fails. Instead of xml like this:
They have this So my IEnumerable object writes all contents of the array but does not create the parent root node of the Array. really sucks. Don't know how those idiots that wrote the system handle the xml to begin with.
-
Almost. But you helped me realize I'm closer than I thought. Seems my base object being passed to the ObjectWalker IS the array list. So I have to step through and find out why it isn't going to the IEnumerableWalker. I have the enumerable walker there because this is where the well-formed xml fails. Instead of xml like this:
They have this So my IEnumerable object writes all contents of the array but does not create the parent root node of the Array. really sucks. Don't know how those idiots that wrote the system handle the xml to begin with.
in this case, i'd consider generating the ouput like and processing xslt transformation later to replace the well-formed array serialisation with desired format.
-
in this case, i'd consider generating the ouput like and processing xslt transformation later to replace the well-formed array serialisation with desired format.
It was considered but I did not care to screw around with XSLT. Horrible stuff, IMHO. But I did get the XmlSerializer working as I needed it. It was just finding where to look to determine the base class of the object. Once I got past that, the rest just flew. It left me with enough time to add the necessary logic to get the attributes, determine if there is an XmlElementAttribute and get the necessary element name. But you post got me headed in the right direction. Turns out that my problem was caused because I fell into the wrong logic path with the ArrayList. That was due to not looking at the right place for the base object type. All working. All done. Thanks for your indirect help.