var doc3 = XDocument.Load(@"C:\Projects\ScanBandConfigTesting\ScanBandConfigTesting\ScanBandConfigSmall.xml");
var scanBand = new ScanBand()
{
ListOfForms = (from form in doc3.Descendants("form")
select new ScanBandForm()
{
FormTypes = form.Attribute("types").Value,
ScanBandNumber = form.Attribute("number").Value,
ListOfRows = (from row in form.Descendants("row")
select new ScanBandRow()
{
AllowSpaces = row.Element("allowSpaces").Value.ToLower() == "true",
SplitCharacter = row.Element("splitCharacter").Value,
ListOfColumns = (from column in row.Descendants("column")
select new ScanBandColumn()
{
AlwaysKey = column.Element("allwaysKey").IsEmpty ? false : column.Element("allwaysKey").Value.ToLower() == "true",
DataTypeString = column.Element("dataType").IsEmpty ? string.Empty : column.Element("dataType").Value,
MatchingFieldName = column.Element("matchingFieldName").IsEmpty ? string.Empty : column.Element("matchingFieldName").Value,
NonField = column.Element("nonField").IsEmpty ? false : column.Element("nonField").Value.ToLower() == "true",
RegularExpressionString = column.Element("regularExpression").IsEmpty ? string.Empty : column.Element("regularExpression").Value,
}).ToList()
}).ToList()
}).ToList()
};
XML
<scanBand>
<form types="FormName" number="1">
<row>
<allowSpaces>false</allowSpaces>
<splitCharacter> </splitCharacter>
<column>
<matchingFieldName>FirstField</matchingFieldName>
<dataType>CB</dataType>
<regularExpression></regularExpression>
<allwaysKey>false</allwaysKey>
<nonField>false</nonField>
</column>
<column>
<matchingFieldName>SecondField</matchingFieldName>
<dataType>CB</dataType>
<regularExpression></regularExpression>
<allwaysKey>false</allwaysKey>
<nonField>false</nonField>
</column>
<column>
<matchingFieldName>ThirdField</matchingFieldName>
<dataType>CB</dataType>
<regularExpression></regularExpression>
<!--<allwaysKey></allwaysKey>-->
<nonField>true</nonField>
</column>
</row>
</form>
</scanBand>
Goal is to have this not blow up when one of the elements in the .xml file don't exist. I tried to play around with .Any() but haven't been successful.
I would rather not iterate through using foreach and would rather stick w/ LINQ
Any help is much appreciated
Do not use Value property to get value of attribute or element. If node is missing, you will get exception. When you casting node (e.g. to string), you will get default value for that type if node is missing. Also you can use ?? operator to provide your own default value for missing string nodes (by default you will get null).
result = (string)column.Element("dataType") ?? String.Empty
Same trick used with boolean values - I get Nullable<bool> and if it's null (node missing) then I assign false if it is not null, then node's value successfully assigned to non-nullable property:
ListOfForms =
(from form in doc3.Descendants("form")
select new ScanBandForm() {
FormTypes = (string)form.Attribute("types"),
ScanBandNumber = (string)form.Attribute("number"),
ListOfRows =
(from row in form.Descendants("row")
select new ScanBandRow() {
AllowSpaces = (bool?)row.Element("allowSpaces") ?? false,
SplitCharacter = (string)row.Element("splitCharacter"),
ListOfColumns =
(from column in row.Descendants("column")
select new ScanBandColumn() {
AlwaysKey = (bool?)column.Element("allwaysKey") ?? false,
DataTypeString = (string)column.Element("dataType") ?? String.Empty,
MatchingFieldName = (string)column.Element("matchingFieldName") ?? String.Empty,
NonField = (bool?)column.Element("nonField") ?? false,
RegularExpressionString = (string)column.Element("regularExpression") ?? String.Empty,
}).ToList()
}).ToList()
}).ToList();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With