Share via

XmlNode null reference in custom configuration file

NICOLAS 60S 21 Reputation points
2022-01-05T13:41:19.967+00:00

Hello everyone.
I have a Xml that I use like config file. When I try to get data from the child node of DWDD007 node, I get a NullReferenceException, and I don´t know why, but I can get the innertext from child node of DWDD004. Can you help me? Thanks, and sorry for my bad english.

Xml File:
<?xml version="1.0" encoding="utf-8"?>
<Report>
<DWDD004>
<Database>xxxxx</Database>
</DWDD004>
<DWDD007>
<Database>yyyyy</Database>

</DWDD007>

</Report>

C# Code:

public static string GetValue(string nameOfReport, string node)
{
string data = "";
if (!File.Exists(ConfigurationFile))
{
Console.WriteLine($"El archivo {ConfigurationFile} no existe.");
Environment.Exit(-1);
}
try
{
_doc = new XmlDocument();
_doc.Load(ConfigurationFile);
data = _doc.SelectSingleNode("//"+ nameOfReport +"/"+node).InnerText;
}
catch (Exception ex)
{
Console.WriteLine(ex.InnerException.ToString());
Environment.Exit(-1);
}
return data;
}

Developer technologies | C#
Developer technologies | C#

An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.


3 answers

Sort by: Most helpful
  1. Yitzhak Khabinsky 27,196 Reputation points
    2022-01-06T15:21:22.28+00:00

    Hi @NICOLAS 60S ,

    What you need is easy to achieve via LINQ to XML.

    I saved your XML into a file on the file system: "e:\Temp\NICOLAS60S-5333.xml".

    XML

    <?xml version="1.0"?>  
    <Report>  
    	<DWDD004>  
    		<Database>xxxxx</Database>  
    	</DWDD004>  
    	<DWDD007>  
    		<Database>yyyyy</Database>  
    	</DWDD007>  
    </Report>  
    

    c#

    void Main()  
    {  
    	const string filename = @"e:\Temp\NICOLAS60S-5333.xml";  
    	const string nameOfReport = "DWDD004";  
      
    	XDocument xdoc = XDocument.Load(filename);  
      
    	string Database = xdoc.Descendants(nameOfReport)  
    		.Elements("Database")  
    		.FirstOrDefault()?.Value;  
    		  
    	Console.WriteLine($"Database='{Database}'");  
    }  
    

    Output

    Database='xxxxx'  
    

    Was this answer helpful?

    0 comments No comments

  2. Lohith GN 516 Reputation points Microsoft Employee
    2022-01-05T23:26:54.72+00:00

    Hi.

    You can use XDocument class of Xml.Linq namespace to do this.

    Here is a code snippet for this:

    //I cant use a file. So creating XML as string for the example
    var xml = "<Report><DWDD004><Database>xxxxx</Database></DWDD004><DWDD007><Database>yyyyy</Database></DWDD007></Report>";
    var xmlReader = new StringReader(xml);
    
    //Use XDocument to load your XML file
    var xmlDoc = XDocument.Load(xmlReader);
    var reportName = "DWDD007";
    var nodeValue = xmlDoc.Document
                                  .Element("Report")
                                  .Element(reportName)
                                  .Element("Database")
                                  .Value;
    
    Console.WriteLine(nodeValue);
    

    Having said that - do consider using JSON as a configuration file instead of XML. JSON is becoming the defacto for these kind of things. Even in .NET configuration files are JSON now. System.Text.Json makes it easy to deserialize your JSON to a Object.

    Hope this helps.

    Was this answer helpful?

    0 comments No comments

  3. Karen Payne MVP 35,606 Reputation points Volunteer Moderator
    2022-01-05T16:57:32.123+00:00

    Have you considered using a json file?

    In the code below, if a Database is null it's set to empty which you can check on or set a default database.

    Using Json.net NuGet package

    public class Report
    {
        public string Name { get; set; }
        public string Database { get; set; } = "empty";
    }
    

    Main class

    public class Reports
    {
        public List<Report> List { get; set; }
    }
    

    Mocking and reading

    public class Mocked
    {
        private static string _fileName = "Reports.json";
        public static void Populate()
        {
            Reports reports = new Reports
            {
                List = new List<Report>
                {
                    new Report() { Name = "DWDD004", Database = "first database" },
                    new Report() { Name = "DWDD007" }
                }
            };
    
            string output = JsonConvert.SerializeObject(reports, Formatting.Indented);
            File.WriteAllText(_fileName, output);
    
        }
    
        public static Reports Load()
        {
            var json = File.ReadAllText(_fileName);
            return JsonConvert.DeserializeObject<Reports>(json);
        }
    }
    

    Sample reading

    Mocked.Populate();
    Reports reports = Mocked.Load();
    
    Console.WriteLine("DWDD004");
    var firstReport = reports.List.FirstOrDefault(x => x.Name == "DWDD004");
    Console.WriteLine(firstReport.Database == "empty" ? "No database name" : firstReport.Database);
    
    Console.WriteLine();
    
    Console.WriteLine("DWDD007");
    var secondReport = reports.List.FirstOrDefault(x => x.Name == "DWDD007");
    Console.WriteLine(secondReport.Database == "empty" ? "No database name" : secondReport.Database);
    

    Json file created above

    {
      "List": [
        {
          "Name": "DWDD004",
          "Database": "first database"
        },
        {
          "Name": "DWDD007",
          "Database": "empty"
        }
      ]
    }
    

    Was this answer helpful?

    0 comments No comments

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.