Reputation: 706
Sorry for the horrible title, I wasn't sure what the proper phrasing is.
I've been using this code to parse some XML:
[Serializable()]
public class Report
{
[XmlElement("AttachedFiles")]
public AttachedFiles attachedFiles;
public Report()
{
attachedFiles = null;
}
}
[Serializable()]
[XmlRoot("nodes")]
public class ReportList
{
[XmlElement("node", typeof(Report))]
public Report[] reportList;
}
[Serializable()]
[XmlRoot("AttachedFiles")]
public class AttachedFiles
{
[XmlElement("AttachedFile")]
public List<string> attachedFiles;
}
The XML looks something like this:
<nodes>
<node>
<AttachedFiles>
<AttachedFile>File1</AttachedFile>
<AttachedFile>File2</AttachedFile>
</AttachedFiles>
</node>
</nodes>
The problem I'm having is that this ends up with me having to call Report.attachedFiles.attachedFiles
to get the List. Is there a way for me to only call Report.attachedFiles
and get the List? I know this is a really minor problem, but it's bothering quite a bit.
EDIT
This is what the code looks like after help from @xDaevax.
[Serializable()]
public class Report
{
[XmlArray(ElementName = "AttachedFiles"), XmlArrayItem(ElementName = "AttachedFile")]
public List<string> AttachedFiles;
public Report()
{
attachedFiles = null;
}
}
[Serializable()]
[XmlRoot("nodes")]
public class ReportList
{
[XmlElement("node", typeof(Report))]
public Report[] reportList;
}
Thanks for the help!
Upvotes: 0
Views: 61
Reputation: 2022
Here is what I came up with (though I did not have your JiraReport class handy).
[Serializable()]
public class Report {
[XmlIgnore()]
private AttachedFiles _attachedFiles;
public Report() {
attachedFiles = null;
} // end constructor
[XmlArray(ElementName = "AttachedFiles"), XmlArrayItem(ElementName = "AttachedFile")]
public AttachedFiles Files {
get { return _attachedFiles; }
set { _attachedFiles = value; }
} // end property Files
} // end class Report
[Serializable()]
[XmlRoot("ReportList")]
public class ReportList {
[XmlIgnore()]
private Report[] _reports;
public ReportList() {
_reports = null;
} // end constructor
[XmlArray(ElementName = "nodes"), XmlArrayItem(ElementName = "node")]
public Report[] Reports {
get { return _reports; }
set { _reports = value; }
} // end property Reports
} // end class ReportList
[Serializable()]
public class AttachedFiles : List<string> {
} // end class AttachedFiles
Using the XmlArray and ArrayItem on a collection property simplifies the attribute usage and makes the code easier to read. Also, because the AttachedFiles class inherits from a list of string, it removes a level of depth from your object graph so the call isn't redundant anymore. You could also add a function on the ReportList class that loops and returns all attached files for all reports for you (functions will not be serialized by the XmlSerializer).
Edit: Here is some MSDN documentation that explains the feature usage:
http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlarrayitemattribute(v=vs.100).aspx Also, see this BlackWasp article that has a nice walkthrough of XML serialization involving arrays. http://www.blackwasp.co.uk/xmlarrays.aspx
Upvotes: 1