Home > Net >  how can i get node Element value From LINQ?
how can i get node Element value From LINQ?

Time:07-25

i have a collection of service users, i want to iterate over ServiceUsers and extract value from ServiceUser, (ID, USER_NAME, UN_ID, IP, NAME)

 <ServiceUsers xmlns="">
  <ServiceUser>
    <ID>280334</ID>
    <USER_NAME>YVELAMGAMOIYENET12:206322102</USER_NAME>
    <UN_ID>731937</UN_ID>
    <IP>91.151.136.178</IP>
    <NAME>?????????????????????: 123456</NAME>
  </ServiceUser>
  <ServiceUser>
    <ID>266070</ID>
    <USER_NAME>ACHIBALANCE:206322102</USER_NAME>
    <UN_ID>731937</UN_ID>
    <IP>185.139.56.37</IP>
    <NAME>123456</NAME>
  </ServiceUser>
</ServiceUsers>

my Code looks like this, but i am getting null point exception.

XDocument doc = XDocument.Parse(xml)
List<XElement> xElementList = doc.Element("ServiceUsers").Descendants().ToList();
foreach (XElement element in xElementList)
{
    string TEST= element.Element("Name").Value;

    comboBoxServiceUser.Items.Add(element.Element("Name").Value);
}

CodePudding user response:

I used the example from XmlSerializer.Deserialize Method as the base for the following snippet that reads the provided xml.

var serializer = new XmlSerializer(typeof(ServiceUsers));

ServiceUsers i;

using (TextReader reader = new StringReader(xml))
{
    i = (ServiceUsers)serializer.Deserialize(reader);
}

[XmlRoot(ElementName = "ServiceUsers")]  
public class ServiceUsers : List<ServiceUser> 
{
}

public class ServiceUser 
{
    [XmlElement(ElementName = "ID")]
    public string Id {get; set;}
}

CodePudding user response:

I think the basis of the problem is your trailing 's' to put it short, You iterate ServiceUser not ServiceUsers

Anyway this runs through fine:

[Fact]
public void CheckIteratorTest()
{
    var a = Assembly.GetExecutingAssembly();
    string[] resourceNames = a.GetManifestResourceNames();
    string nameOf = resourceNames.FirstOrDefault(x => x.Contains("SomeXml"));
    Assert.NotNull(nameOf);

    using var stream = a.GetManifestResourceStream(nameOf);
    Assert.NotNull(stream);

    var reader = new StreamReader(stream, Encoding.UTF8);
    var serialized = reader.ReadToEnd();

    var doc = XDocument.Parse(serialized);

    var elemList = doc.Root.Elements("ServiceUser").ToList();
    Assert.NotEqual(0, elemList.Count);
    foreach(var serviceUser in elemList)
    {
        System.Diagnostics.Debug.WriteLine($"Name : {serviceUser.Name ?? "n.a."}");
    }
}

CodePudding user response:

As being said: XML is case-sensitive. Next issue is .Descendants() returns all the descendant nodes, nested ones, etc, 12 nodes in this case. So NullPointerException will happen even if you fix a "typo".

Here is your fixed code:

XDocument doc = XDocument.Parse(xml);
var xElementList = doc
    .Element("ServiceUsers") // picking needed root node from document
    .Elements("ServiceUser") // picking exact ServiceUser nodes
    .Elements("NAME")  // picking actual NAME nodes
    .ToList();
foreach (XElement element in xElementList)
{
    var TEST = element.Value;
    Console.WriteLine(TEST); // do what you were doing instead of console
}

CodePudding user response:

Use doc.Element("ServiceUsers").Elements() to get the<ServiceUser> elements. Then you can loop over the child values of those in a nested loop.

var doc = XDocument.Parse(xml);
foreach (XElement serviceUser in doc.Element("ServiceUsers").Elements()) {
    foreach (XElement element in serviceUser.Elements()) {
        Console.WriteLine($"{element.Name} = {element.Value}");
    }
    Console.WriteLine("---");
}

Prints:

ID = 280334
USER_NAME = YVELAMGAMOIYENET12:206322102
UN_ID = 731937
IP = 91.151.136.178
NAME = ?????????????????????: 123456
---
ID = 266070
USER_NAME = ACHIBALANCE:206322102
UN_ID = 731937
IP = 185.139.56.37
NAME = 123456
---

Note: Elements() gets the (immediate) child elements where as Descendants() returns all descendants. Using Elements() gives you a better control and allows you to get the properties grouped by user.

You can also get a specific property like this serviceUser.Element("USER_NAME").Value. Note that the tag names are case sensitive!

  • Related