XML parse check if attribute exist
Asked Answered
R

3

21

I've made a method which checks if an attribute exist in a XML-file. If it does not exist it returns "False". It works but it takes a very long time to parse the file. It seems it reads the whole file for each single row. Have I missed something here? Can I make it more effective somehow?

    public static IEnumerable<RowData> getXML(string XMLpath)
    {
        XDocument xmlDoc = XDocument.Load("spec.xml");

        var specs = from spec in xmlDoc.Descendants("spec")
                    select new RowData
                    {
                        number= (string)spec.Attribute("nbr"),
                        name= (string)spec.Attribute("name").Value,
                        code = (string)spec.Attribute("code").Value,
                        descr = (string)spec.Attribute("descr").Value,
                        countObject = checkXMLcount(spec),


        return specs;
    }

    public static string checkXMLcount(XElement x)
    {
        Console.WriteLine(x.Attribute("nbr").Value);
        Console.ReadLine();
        try
        {
            if (x.Attribute("mep_count").Value == null)
            {
                return "False";
            }
            else
            {
                return x.Attribute("mep_count").Value;
            }
        }
        catch
        {
            return "False";
        }
    }

I tested to replace the method with one that only returns and receive string:

public static string checkXMLcount(string x)
{
    Console.WriteLine(x);
    Console.ReadLine();
    return x;

}

I made a XML-file with only one single row. The console prints out the value 15 times. Any ideas?

Relapse answered 12/11, 2012 at 10:34 Comment(1)
Why write your own version of XPath, I wonder?Pallid
R
47

Solved! No extra method needed:

countObject = spec.Attribute("mep_count") != null ? spec.Attribute("mep_count").Value : "False",
Relapse answered 13/11, 2012 at 12:22 Comment(1)
If you have alot of these...you can encapsulate ....... private string SafeAttributeValue(XAttribute xattr) { string returnValue = string.Empty; if (null != xattr) { returnValue = (string)xattr.Value; } return returnValue; }Dennison
M
3

Just wanted to point out:

countObject = spec.Attribute("mep_count")?.Value;

Which works all the way up the chain:

countObject = spec?.Attribute("mep_count")?.Value

This will produce the same effect where countObject will be set to null or the value if it exists.

Muntin answered 24/6, 2020 at 3:12 Comment(0)
O
2

You can try this and see if there is any improvement

class xmlAttributes
{
    public string Node;
    public Dictionary<string, string> Attributes;
} 

Now with this LINQ,all attributes are stored in a dictionary(per Node) and could be accessed through the attribute name.

var Result = XElement.Load("somedata.xml").Descendants("spec")
                      .Select(x => new xmlAttributes
                      {
                          Node = x.Name.LocalName,
                          Attributes = x.Attributes()
                                     .ToDictionary(i => i.Name.LocalName,
                                                        j => j.Value)
                      });

Checks if an attribute exists on all XML Nodes

var AttributeFound = Result.All(x => x.Attributes.ContainsKey("AttrName"));

Checks if the attribute appears at least once

var AttributeFound = Result.Any(x => x.Attributes.ContainsKey("AttrName"));
Orangy answered 12/11, 2012 at 11:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.