Khaine775
Khaine775

Reputation: 2765

Retrieving specific data from XML file

Using LINQ to XML.

I have an XML file which looks like this:

<?xml version="1.0" encoding="utf-8"?>
<TileMap xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"     xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Title>title</Title>
  <Abstract>Some clever text about this.</Abstract>
  <SRS>OSGEO:41001</SRS>
  <Profile>global-mercator or something</Profile>
</TileMap>

I can retrieve the <Title> from this with no problems by using this little piece of code:

string xmlString = AppDomain.CurrentDomain.BaseDirectory + @"Capabilities\" + name + ".xml";
string xmlText = File.ReadAllText(xmlString);
byte[] buffer = Encoding.UTF8.GetBytes(xmlText);
XElement element = XElement.Load(xmlString);
IEnumerable<XElement> title =
                            from el in element.Elements("Title")
                            select el;
foreach (XElement el in title)
{
    var elementValue = el.Value;
}

However, this isn't very flexible because say I have an XML file that looks like this:

<?xml version="1.0" encoding="utf-8"?>
<RootObject xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"     xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Services>
    <TileMapService>
      <Title>title</Title>
      <href>http://localhost/root</href>
    </TileMapService>
  </Services>
</RootObject>

It can't find <Title> but it finds <Services> (I presume) but since it's not called "Title" it just ignores it. I'm not very strong in working with XML. How would I go about making a method that looks through the XML and fetches me "Title" or however you'd implement this?

Upvotes: 0

Views: 73

Answers (3)

maruthu chandrasekaran
maruthu chandrasekaran

Reputation: 168

Descendants will select all the "Title" elements irrespective of the level. Please use xpath to correctly locate the element

using System;
using System.Linq;
using System.Xml.Linq;
using System.Xml.XPath;                 
using System.IO;

public class Program
{
    public static void Main()
    {
        string xmlFile = AppDomain.CurrentDomain.BaseDirectory + @"Capabilities\" + name + ".xml";
        XElement xml=XElement.Load(xmlFile);
        IEnumerable<XElement> titleElements = xml.XPathSelectElements("//Services/TileMapService/Title");
    }
}

Upvotes: 0

Jon Skeet
Jon Skeet

Reputation: 1503290

You're currently just looking at the child elements of the root element.

Instead, if you want to find all descendants, use Descendants.

Additionally, there's no point in using a query expression of from x in y select x (or rather, there's a very limited point in some cases, but not here). So just use:

var titles = element.Descendants("Title");

Personally I would actually use XDocument here rather than XElement - you have after all got a whole document, complete with XML declaration, not just an element.

Upvotes: 2

Damir Arh
Damir Arh

Reputation: 17865

Change your LINQ query to:

IEnumerable<XElement> title =
    from el in element.Descendants("Title")
    select el;

Elements returns only the immediate children, Descendants returns all descendant nodes instead.

Upvotes: 1

Related Questions