0

I have following XML file that I am parsing using XML serializer.

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Projects>
    <Global>
        <Variables>
            <Variable name="GlobalVar1" value="GV1"/>
            <Variable name="GlobalVar2" value="GV2"/>
        </Variables>
    </Global>
    <Project>
        <Variables>
            <Variable name="LocalVar1" value="LV1"/>
            <Variable name="LocalVar2" value="LV2"/>
        </Variables>
    </Project>
</Projects>

I am building a dictionary of variables - name-value pairs. I wrote following LINQ statement which works fine (assume that I don't have duplicate variable names in global and project scope):

Dictionary<String, String> varDict = Projects.Global.Variables.Select(var => new { var.name, var.value })
                .Union(Projects.Project.Variables?.Select(var => new { var.name, var.value }))
                .ToDictionary(var => var.Key, var => var.value);

Now I have a twist - sometimes either the entire <Global> tag will be missing or it won't have the <Variables> tag. Likewise, sometimes <Variables> tag will be missing from the <Project> tag. For example: the XML file will be:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Projects>
    <Project>
        <Variables>
            <Variable name="LocalVar1" value="LV1"/>
            <Variable name="LocalVar2" value="LV2"/>
        </Variables>
    </Project>
</Projects>

I thought using ?. operator (null-conditional), as follows, would help, but when <Global> tag is missing the following LINQ statement returns null (varDict is null):

Dictionary<String, String> varDict = Projects.Global?.Variables?.Select(var => new { var.name, var.value })
                .Union(Projects.Project.Variables?.Select(var => new { var.name, var.value }))
                .ToDictionary(var => var.Key, var => var.value);

What am I doing wrong or what is the solution?

2
  • I suspect there is a serious misunderstanding of how this works. Please show the code you are using to deserialize the XML. Commented Oct 19, 2019 at 20:20
  • You don't have Global anymore, you can think of Global? like if(Global != null) ..do..... Commented Oct 19, 2019 at 20:24

1 Answer 1

1

The ?. operator just avoids throwing a NullReferenceException. It still returns null.

// If Projects.Global is null:
var var1 = Projects.Global?.Variables; // Does not throw an exception, but var1 is null
var var2 = Projects.Global.Variables; // Blows up and throws a NullReferenceException

If you want the .Union() to work when the first part is null, it needs something to work off of. So something like should work (may need some tweaking):

var globalValues = Projects.Global?.Variables?.Select(var => new KeyValuePair<string, string>(var.name, var.value)) 
        ?? new List<KeyValuePair<string, string>>();

Dictionary<String, String> varDict = globalValues
        .Union(Projects.Project.Variables?.Select(var => new KeyValuePair<string, string>(var.name, var.value)))
        .ToDictionary(var => var.Key, var => var.Value);
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.