Say I have a export (Serialize) function that does the following
public void ExportToXML()
{
var DCS = new DataContractSerializer(typeof(Entry));
var XWriter = XmlWriter.Create(@"C:\Temp\Export.xml");
XWriter.WriteStartDocument();
XWriter.WriteStartElement("Entries");
Entries.ForEach(e =>
{
DCS.WriteStartObject(XWriter, e);
DCS.WriteObjectContent(XWriter, e);
DCS.WriteEndObject(XWriter);
});
XWriter.WriteEndElement();
XWriter.WriteEndDocument();
XWriter.Close();
}
exports an XML file that looks like
<Entries>
<Entry>{Some Data}</Entry>
<Entry>{Some Data}</Entry>
<Entry>{Some Data}</Entry>
<Entry>{Some Data}</Entry>
</Entries>
For the Import method I want to deserialize each
<Entry>{Some Data}</Entry>one at a time so that I can apply a transform
Func<Entry,Entry>
if a
Func<Entry,bool>
predicate is true
This is what I came up with
public void ImportFromXML(string FileName, Func<Entry,Entry> Transform, Func<Entry,bool> DoTransform)
{
var DCS = new DataContractSerializer(typeof(Entry));
var ImportedEntries = new List<Entry>();
foreach (var EntryElement in XDocument.Load(FileName).Root.Elements().Where(xe => xe.Name.LocalName == "Entry"))
{
var XMLEntry = (Entry)DCS.ReadObject(EntryElement.CreateReader());
ImportedEntries.Add(DoTransform(XMLEntry) ? Transform(XMLEntry) : XMLEntry);
}
entries = ImportedEntries.ToDictionary(e => e.KeyName + "\\" + e.ValueName);
}
Which works but I'm wondering if there is a way to do this in one shot with a single XmlReader as opposed to generating each XElement's XMLReader.
I tried to reverse the logic of the Export method
public void ImportFromXML(string FileName, Func<Entry,Entry> Transform, Func<Entry,bool> DoTransform)
{
var DCS = new DataContractSerializer(typeof(Entry));
var ImportedEntries = new List<Entry>();
var XReader = XmlReader.Create(@"C:\Temp\Export.xml");
XReader.ReadStartElement("Entries");
while (!{WHAT Exit Condition?})
{
var XMLEntry = (Entry)DCS.ReadObject(XReader());
ImportedEntries.Add(DoTransform(XMLEntry) ? Transform(XMLEntry) : XMLEntry);
}
XReader.Close();
entries = ImportedEntries.ToDictionary(e => e.KeyName + "\\" + e.ValueName);
}
However I'm not sure what to put in for
{WHAT Exit Condition?}obviously I can't use
!XReader.EOFas reading to the end of file will cause it to try and deserialize the closing </Entries> tag as an Entry.
The class these methods are part of will be consumed as part of our SCCM OS deployment task sequences, which means they could be used by multiple concurrently running task sequences that are querying the source XML files over the network. So I'm a little concerned with better performance.
Am I chasing my tail trying to do this with a single XmlReader or is using the combination of LINQ to XML with separate XmlReaders the best option?