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("Report",
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");
}
}
}
[quoted text, click to view] "Keith Patrick" <richard_keith_patrick@nospamhotmail.com> wrote in message
news:%23TMU$W5aEHA.384@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" <Greg@discussions.microsoft.com> wrote in message
> news:986F1DBA-46EA-4604-8251-3854A3EDEDFF@microsoft.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.
>
>