Linq to Xml is printing only first descendant value

萝らか妹 提交于 2019-12-11 01:56:56

问题


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); }
    }
}

回答1:


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



回答2:


Instead of control.Element("Property") which select single one, use control.Elements("Property") which select all with Property

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

 }


来源:https://stackoverflow.com/questions/40135859/linq-to-xml-is-printing-only-first-descendant-value

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!