bkolluru bkolluru - 1 month ago 11
C# Question

Linq to Xml is printing only first descendant value

The following code is printing

Building Phone
but not printing
uxPhone
.

1) Should I be getting a collection of
Property
descendants maybe?

2) This seems pretty verbose, is there a shorter form of doing this?

var xmlstr =
@"<Form>
<ControlsLayout>
<Object type='sometype' children='Controls'>
<Property name='ControlLabel'>BuildingPhone</Property>
<Property name='Name'>uxPhone</Property>
</Object>
</ControlsLayout>
</Form>";

XElement xelement = XElement.Parse(xmlstr);
var controls = xelement.Descendants("Object");
foreach (var control in controls)
{
var xElement = control.Element("Property");
if (xElement != null)
{
var xAttribute = xElement.Attribute("name");
if (xAttribute != null && xAttribute.Value == "ControlLabel")
{ Console.WriteLine(xElement.Value); }
if (xAttribute != null && xAttribute.Value == "Name")
{ Console.WriteLine(xElement.Value); }
}
}

Answer

Should I be getting a collection of Property descendants maybe?

The use of the Element function in control.Element("Property") returns a single element. You want instead to use Elements.

This seems pretty verbose, is there a shorter form of doing this?

A nicer way all together is to use Descendants("Property") (which searches recursively in your xml and returns the collection of elements of the <> you specified) and instead of if statements to use a where clause:

XElement xelement = XElement.Parse(xmlstr);
var result = from element in xelement.Descendants("Property")
             let attribute = element.Attribute("name")
             where (attribute != null && attribute.Value == "ControlLabel" )||
                   (attribute != null && attribute.Value == "Name" )
             select element.Value;

foreach(var item in result)
    Console.WriteLine(item);

// Building Phone
// uxPhone