for an alternative approach in which you do not iterate on the XML or on
each item, see the example below.
-Dino
// reports.cs
//
// build with:
// csc /target:exe /out:a.exe reports.cs
//
// Sat, 17 Jul 2004 15:23
//
using System.Xml.Serialization;
namespace Ionic {
public class Report {
[System.Xml.Serialization.XmlElementAttribute(Form= System.Xml.Schema.XmlSche
maForm.Unqualified)]
public string Title;
[System.Xml.Serialization.XmlElementAttribute(Form= System.Xml.Schema.XmlSche
maForm.Unqualified)]
public string Notes;
[System.Xml.Serialization.XmlText]
public string Something;
}
[System.Xml.Serialization.XmlRoot("Reports", Namespace="",
IsNullable=false)]
[System.Xml.Serialization.XmlType("Reports", Namespace="")]
public class ReportCollection {
[System.Xml.Serialization.XmlElementAttribute("Repo rt",
Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
public Report[] Items;
public ReportCollection() {
// null constructor must not de-serialize, else you get an endless
loop (stack overflow)
}
// one approach is to use a parameterized constructor.
// this param in this case is an xml string, but it need not be.
// it could be the name of an XML file, a stream, whatever.
public ReportCollection(string s) {
ReportCollection temp= ReportCollection.CreateFromString(s);
Items= temp.Items; // shallow copy of array. Would need to do this
for each field in the RC type
// "temp" now goes out of scope but the Items array gets referenced by
"this"
}
// another approach: use a public static factory method.
// user could call as above (as shown in the parameterized constructor)
public static ReportCollection CreateFromString(string xml1) {
// could parameterize this with a filename, a stream, a string,
whatever
XmlSerializer s1 = new XmlSerializer(typeof(ReportCollection));
// slurp it in: deserialize the original XML into a value
System.IO.StringReader sr= new System.IO.StringReader(xml1);
ReportCollection rc= (ReportCollection) s1.Deserialize(new
System.Xml.XmlTextReader(sr));
return rc;
}
}
public class TestDriver {
static void Main(string[] args) {
string xml1=
"<Reports>\n" +
" <Report>\n" +
" <Title>some title</Title>\n" +
" <Notes> some notes </Notes>\n" +
" </Report>\n" +
" <Report>\n" +
" blah blah blah\n" +
" </Report>\n" +
"</Reports>\n" +
"";
// Show the original XML
System.Console.WriteLine("\n====================== ======================\n\n
\nSource XML:\n{0}", xml1);
// spit it out: show the value we got
System.Console.WriteLine("\n\n\nDe-serialize then Serialize to
System.Console.Out:\n");
ReportCollection rc= new ReportCollection(xml1);
// could also use the factory method:
// ReportCollection rc= ReportCollection.CreateFromString(xml1);
XmlSerializer s1 = new XmlSerializer(typeof(ReportCollection));
// use this to "suppress" the default xsd and xsd-instance namespaces
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add( "", "" );
s1.Serialize(System.Console.Out, rc, ns);
System.Console.WriteLine("\n\n");
}
}
}
"Keith Patrick" <ri*******************@nospamhotmail.com> wrote in message
news:%2***************@TK2MSFTNGP10.phx.gbl...
XmlSerializer serializer = new XmlSerializer(typeof(Report));
ArrayList reportList = new ArrayList();
XmlNode reports = ???; // XPath is good here if you've got a document
rather than a source node or are pulling from a DB
foreach (XmlNode report in reports.ChildNodes) {
if (!(report is XmlElement)) {
continue;
}
reportList.Add(serializer.Deserialize(new XmlNodeReader(report)));
}
"Greg" <Gr**@discussions.microsoft.com> wrote in message
news:98**********************************@microsof t.com... I'm writing a class in C# ....
I have a collection calls Reports made up of Report objects. I'm trying to deserialize an XML file that looks like : <Reports>
<Report>
<Title>some title</Title>
<Notes> some notes </Notes>
</Report>
<Report>
blah blah blah
</Report>
</Reports>
-------------------------------------------------------------------
I want to be able to deserialize the file in the Reports collection
constructor and build the Report objects on the fly. The only examples
I've been able to find read the entire XML file outside of the class (which
works fine in my test console app), but I want to be able to be able to
dynamically build everything inside the collection class. Do I need to
parse through the XML file and got to each <Report> tag and deserialize
one Report at a time (and use "this.Add(newReport)")? How can parse the file
like that and pass just that info into the deserialize method? I haven't
used XPath, so if I need that, an example would really help.