Read an XML with Linq

I read a xml configfile for a C# application with Linq

Is there any easier way then my code (checking for null)
foreach (XElement products in selfdefproducts.Elements("products"))
                    {
                        if (!string.IsNullOrEmpty(products.Value))
                        {
                            if (! string.IsNullOrEmpty(products.Element("name").Value))
                            {
                                String swName = products.Element("name").Value;
                            }
 
                            if (! string.IsNullOrEmpty(products.Element("size").Value))
                            {
                                UInt32 swSize = Convert.ToUInt32(products.Element("size").Value);
                            }
 
                            if (!string.IsNullOrEmpty(products.Element("companyname").Value))
                            {
                                String swCompany = products.Element("companyname").Value;
                            }
 
                            if (!string.IsNullOrEmpty(products.Element("version").Value))
                            {
                                String swVersion = products.Element("version").Value;
                            }
 
                            // Generate Object
                            SoftwareSelfDefined myDefProd = SoftwareSelfDefined.buildSwObject(swName,swSize,swCompany,swVersion);
 
                            // Add to List
                            productsSet.Add(myDefProd);
 
                        }
                    }

Open in new window

schubdueseAsked:
Who is Participating?
 
abelCommented:
I would actually remove all the IsNullOrEmpty declarations and just add the values to the buildSwObject. Btw, does your code compile? Because all the declarations of the variables are inside the scopes of the if-statements and cannot be accessed by the buildSwObject.

Try it without all the ifs like this:

int swSize = 0;int.TryParse(products.Element("size").Value, swSize);SoftwareSelfDefined myDefProd = SoftwareSelfDefined.buildSwObject(    products.Element("name").Value,    swSize,    products.Element("companyname").Value,    products.Element("version").Value);

0
 
CuteBugCommented:
In your code, there can be a scenario where
products.Element("name") is null... in which case, products.Element("name").Value will throw an exception.

A better implementation for your code is
foreach (XElement products in selfdefproducts.Elements("products"))
{
		if (products == null)
			continue;
	
		String swName = string.Empty;
		UInt32 swSize = 0;
		String swCompany = string.Empty;
		String swVersion = string.Empty;
		
		if (products.Element("name") != null)
        {
            swName = products.Element("name").Value;
        }
 
        if (products.Element("size").Value != null)
        {
            swSize = Convert.ToUInt32(products.Element("size").Value);
        }
 
        if (products.Element("companyname") != null)
        {
            swCompany = products.Element("companyname").Value;
        }
 
        if (products.Element("version").Value != null)
        {
            swVersion = products.Element("version").Value;
        }
 
        // Generate Object
        SoftwareSelfDefined myDefProd = SoftwareSelfDefined.buildSwObject(swName,swSize,swCompany,swVersion);
 
        // Add to List
        productsSet.Add(myDefProd);
    }
}

Open in new window

0
 
abelCommented:
inside the buildSwObject method you can have something like this:


public SoftwareSelfDefined buildSwObject(string name, int size, string company, string version)
 {
    // allowing null for each value will show the default for that parameter:
    name = name == null ? "<noname>" : name;
    company = company == null ? "<nocompany>" : company;
    version = version == null ? "0.1" : version;
 
    // your code
}

Open in new window

0
Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

 
CuteBugCommented:
Hi,
There was a typo in the code which i gave.

Here is the correct code
foreach (XElement products in selfdefproducts.Elements("products"))
{
        if (products == null)
                continue;
        
        String swName = string.Empty;
        UInt32 swSize = 0;
        String swCompany = string.Empty;
        String swVersion = string.Empty;
                
        if (products.Element("name") != null)
        {
            swName = products.Element("name").Value;
        }
 
        if (products.Element("size") != null)
        {
            swSize = Convert.ToUInt32(products.Element("size").Value);
        }
 
        if (products.Element("companyname") != null)
        {
            swCompany = products.Element("companyname").Value;
        }
 
        if (products.Element("version") != null)
        {
            swVersion = products.Element("version").Value;
        }
 
        // Generate Object
        SoftwareSelfDefined myDefProd = SoftwareSelfDefined.buildSwObject(swName,swSize,swCompany,swVersion);
 
        // Add to List
        productsSet.Add(myDefProd);
    }
}

Open in new window

0
 
schubdueseAuthor Commented:
abel, you were right... It didn't compile... I changed it right after submitting the question :)

thanks guys
0
 
abelCommented:
you're welcome, glad we could be of some help :)
0
 
schubdueseAuthor Commented:
uhm a little remark after another rewrite:

If the tags are in the xml (e.g. <name></name>) but do not have any value, then the test for != null doesn't work. It always jumps into the routine with

Does not work:
if (product.Element("name").Value  != null)


Works:
if (! string.IsNullOrEmpty(product.Element("name").Value))

Any Idea why?
0
 
abelCommented:
I thought you wanted to work without all the if-statements, like you said in the beginning.

Anyway, testing for null is something else as testing for empty string. If a string is empty it is not null...

string myString = "";
if ( string.IsNullOrEmpty(myString) )   // true

if ( myString == null )   // false

if ( myString == null || myString ==  string.Empty )   // true

if ( myString == "" )   // true

and myString is the same as you Value when the element is empty.
0
 
schubdueseAuthor Commented:
Well i thought about an easier way, but it looks like the most userfriendly code is the one with checking for null and empty...
0
 
abelCommented:
I don't know how you start your code, you haven't shown your final code, but what I would do, if you want to combine the idea of my short solution with your idea of readability, is create a simple method that takes a string and returns a default value, also a string.

// method:
public string GetDefaultString(string input, string default)
{
    if(string.IsNullOrEmpty(input))
    {
         return default;
    }
    else
    {
        return input;
    }
}
 
// inside your current function you can now do this:
foreach (XElement products in selfdefproducts.Elements("products"))
{
        if (products == null)
                continue;
        
        String swName = GetDefaultString(products.Element("name"), "");
        UInt32 swSize = int.Parse(GetDefaultString(products.Element("size"), "0"));
        String swCompany = GetDefaultString(products.Element("companyname"), "");
        String swVersion = GetDefaultString(products.Element("version").Value, "");
 
    ...... etc, no if-statement anymore ....

Open in new window

0
 
schubdueseAuthor Commented:
Good idea, I will do it like this

Thanks
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.