Linq to Object / XML where element doesn't exist

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>&#32;</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>

      

The goal is to prevent this from exploding when one of the elements in the XML file doesn't exist. I tried to play around with .Any () but was not successful.

I would rather not iterate with foreach and rather stick with w / LINQ

Any help is greatly appreciated

+3


source to share


1 answer


Don't use a property Value

to get the value of an attribute or element. If node is missing, you will get an exception. When you produce a node (to a string, for example), you will get the default for that type if node is missing. Also you can use the operator ??

to provide your own default for missing row nodes (you will get null by default).

result = (string)column.Element("dataType") ?? String.Empty

      



Same trick used with boolean values ​​- I get Nullable<bool>

and if it is null

(node ​​is missing) then I assign false

, if it is not null

then node value Invalid 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();

      

+6


source







All Articles