4

Bonjour,

I have an xml doc:

<ns2:feeds xmlns:ns2="XXXX" xmlns="XXXXX" version="3.0">
    <ns2:feed>
        <name>XXX</name>
    </ns2:feed>
    <ns2:feed>
        <name>XXX</name>
    </ns2:feed>
    <ns2:feed>
        <name>XXX</name>
    </ns2:feed>
</ns2:feeds>

How can I use LinqToXml to get a list of Name properties? nothing I try seems to work...

var doc = XDocument.Load(@"feed.xml");

var names = doc
.XPathSelectElements("/*/*[localname()='feeds']") //What should the Xpath be, here?
.Select(p => new 
{ 
    Name = p.Descendants("name").First().Value
})
.ToList();

Is there a simple way to achieve this?

1
  • 2
    Does this work? XNamespace ns = "XXXXX"; and then p.Descendants(ns + "name").First().Value. Commented Aug 14, 2013 at 11:42

3 Answers 3

8

You can do this

XNamespace ns = XNamespace.Get("XXXX");
var listOfNames = doc.Descendants(ns + "feed")
                     .Select(x => x.Elements().First().Value).ToList();

+1 for lazyberezovsky's answer. If you need to specify the element name (name in this case) or you could have multiple name elements then you need to add a second namespace for those elements.

XNamespace ns2 = XNamespace.Get("XXXXX");
var listOfNames = doc.Root.Descendants(ns2 + "name").Select(x => x.Value).ToList();
Sign up to request clarification or add additional context in comments.

4 Comments

XNamespace.Get() doesn't seem to be the best approach here.
Usually with namespaces I've used the above but maybe it hasn't always been efficient in that case. What would be the alternate way?
If you are really concerned about efficiency, you could parse the xml with XmlReader.
@ChristopherStevenson - Not too concerned about efficiency in performance terms but in the way that XNameSpace.Get not being the best approach.
6

With XPathSelectElements you should provide namespace manager in order to use namespaces in XPath query:

var manager = new XmlNamespaceManager(new NameTable());
manager.AddNamespace("ns2", "XXXX");
manager.AddNamespace("ns", "XXXXX"); // default namespace

var names = from n in xdoc.XPathSelectElements("//ns2:feed/ns:name", manager)
            select (string)n;

Without XPath you should use XNamespace when providing name of node to find:

XNamespace ns = "XXXXX";
XNamespace ns2 = "XXXX";

var names = from f in xdoc.Descendants(ns2 + "feed")
            select (string)f.Element(ns + "name");

Comments

4

To get rid of namespaces in XLinQ queries, use similar method mentioned below:

String xml_string = @"<ns2:feeds xmlns:ns2=""XXXX"" xmlns=""XXXXX"" version=""3.0"">
                          <ns2:feed>
                              <name>XXX</name>
                          </ns2:feed>
                          <ns2:feed>
                              <name>YYY</name>
                          </ns2:feed>
                          <ns2:feed>
                              <name>ZZZ</name>
                          </ns2:feed>
                      </ns2:feeds>";

var query = XElement.Parse(xml_string).Descendants()
           .Where(c => c.Name.LocalName.ToString() == "name")
           .ToArray();

foreach (String item in query)
{
    Console.WriteLine(item);
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.