简体   繁体   中英

Linq to xml how to get XElement by value in c#

I have an xml:

<?xml version="1.0" encoding="utf-8"?>
<Fields>
  <Field>
    <Name>DEMOFIELD</Name>
    <Category>HardwareSoftwareRequirement</Category>
  </Field>
</Fields>

When I do this:

XElement xDoc = XElement.Load("File.xml");                
var x= xDoc.Descendants("Field").Where(elem => elem.Value == "DEMOFIELD");//returns no element

This is not returning anything. But when I instead do this:

var x= xDoc.Descendants("Field").Where(elem => elem.Value.Contains( "DEMOFIELD"));//returns no element

On iteration, instead of e.Value , it returns: DEMOFIELDHardwareSoftwareRequirement , can't it just be DEMOFIELD ?

And then iterate through to get the value,

foreach(XElement e in x)
{
    _log.Debug(e.Value);//no value here
}

You need to be sure you are comparing the value of the right elements, it's easy to get this wrong with nested XML. In your case, you are comparing the Field element's value (which will be all of the inner values concatenated), but you mean to compare it to the Name element.

Try this:

var xml = @"<?xml version=""1.0"" encoding=""utf-8""?>
<Fields>
  <Field>
    <Name>DEMOFIELD</Name>
    <Category>HardwareSoftwareRequirement</Category>
  </Field>
</Fields>";
var xdoc = XDocument.Load(new StringReader(xml));
var x = xdoc.Descendants("Field").Where(elem => elem.Element("Name")?.Value == "DEMOFIELD");

You still have the Field element now, so you if you want to get the category you'll need to do something like:

x.First().Element("Category").Value

Code in the post gets node by value, but it is not the node you are looking for.

xDoc.Descendants("Field") selects all nodes named "Field", but that node has only child nodes. So when you call .Value on that node the value is computed by concatenation of all children's values ("DEMOFIELD" + "HardwareSoftwareRequirement" = "DEMOFIELDHardwareSoftwareRequirement").

Depending on what you actually looking for you either need to select all "Name" nodes and filter by value or check value of child node called "Name":

  var nameByValue = xDoc.Descendants("Name")
        .Where(elem => elem.Value == "DEMOFIELD");
  var fieldByChildValue = xDoc.Descendants("Field")
        .Where(elem => elem.Element("Name").Value == "DEMOFIELD");

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM