• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 413
  • Last Modified:

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

0
schubduese
Asked:
schubduese
  • 5
  • 4
  • 2
2 Solutions
 
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
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
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

Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

  • 5
  • 4
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now