[c#] How do I check particular attributes exist or not in XML?

Part of the XML content:

<section name="Header">
  <placeholder name="HeaderPane"></placeholder>
</section>

<section name="Middle" split="20">
  <placeholder name="ContentLeft" ></placeholder>
  <placeholder name="ContentMiddle"></placeholder>
  <placeholder name="ContentRight"></placeholder>
</section>

<section name="Bottom">
  <placeholder name="BottomPane"></placeholder>
</section>

I want to check in each node and if attribute split exist, try to assign an attribute value in a variable.

Inside a loop, I try:

foreach (XmlNode xNode in nodeListName)
{
    if(xNode.ParentNode.Attributes["split"].Value != "")
    {
        parentSplit = xNode.ParentNode.Attributes["split"].Value;
    }
}

But I'm wrong if the condition checks only the value, not the existence of attributes. How should I check for the existence of attributes?

This question is related to c# xml

The answer is


You can use LINQ to XML,

XDocument doc = XDocument.Load(file);

var result = (from ele in doc.Descendants("section")
              select ele).ToList();

foreach (var t in result)
{
    if (t.Attributes("split").Count() != 0)
    {
        // Exist
    }

    // Suggestion from @UrbanEsc
    if(t.Attributes("split").Any())
    {

    }
}

OR

 XDocument doc = XDocument.Load(file);

 var result = (from ele in doc.Descendants("section").Attributes("split")
               select ele).ToList();

 foreach (var t in result)
 {
     // Response.Write("<br/>" +  t.Value);
 }

Just for the newcomers: the recent versions of C# allows the use of ? operator to check nulls assignments

parentSplit = xNode.ParentNode.Attributes["split"]?.Value;

You can use the GetNamedItem method to check and see if the attribute is available. If null is returned, then it isn't available. Here is your code with that check in place:

foreach (XmlNode xNode in nodeListName)
{
    if(xNode.ParentNode.Attributes.GetNamedItem("split") != null )
    {
        if(xNode.ParentNode.Attributes["split"].Value != "")
        {
            parentSplit = xNode.ParentNode.Attributes["split"].Value;
        }
    }  
}

EDIT

Disregard - you can't use ItemOf (that's what I get for typing before I test). I'd strikethrough the text if I could figure out how...or maybe I'll simply delete the answer, since it was ultimately wrong and useless.

END EDIT

You can use the ItemOf(string) property in the XmlAttributesCollection to see if the attribute exists. It returns null if it's not found.

foreach (XmlNode xNode in nodeListName)
{
    if (xNode.ParentNode.Attributes.ItemOf["split"] != null)
    {
         parentSplit = xNode.ParentNode.Attributes["split"].Value;
    }
}

XmlAttributeCollection.ItemOf Property (String)


If your code is dealing with XmlElements objects (rather than XmlNodes) then there is the method XmlElement.HasAttribute(string name).

So if you are only looking for attributes on elements (which it looks like from the OP) then it may be more robust to cast as an element, check for null, and then use the HasAttribute method.

foreach (XmlNode xNode in nodeListName)
{
  XmlElement xParentEle = xNode.ParentNode as XmlElement;
  if((xParentEle != null) && xParentEle.HasAttribute("split"))
  {
     parentSplit = xParentEle.Attributes["split"].Value;
  }
}

var splitEle = xn.Attributes["split"];

if (splitEle !=null){
    return splitEle .Value;
}

Another way to handle the situation is exception handling.

Every time a non-existent value is called, your code will recover from the exception and just continue with the loop. In the catch-block you can handle the error the same way you write it down in your else-statement when the expression (... != null) returns false. Of course throwing and handling exceptions is a relatively costly operation which might not be ideal depending on the performance requirements.