tags:

views:

134

answers:

2

I have a following XML (part of a .rdl report):

<Report xmlns:rd="http://schemas.microsoft.com/SQLServer/reporting/reportdesigner" xmlns="http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition"&gt;
  <DataSources>
    <DataSource Name="TMSSharepointDataSource">
      <DataSourceReference>TMSSharepointDataSource</DataSourceReference>
      <rd:DataSourceID>f06ffa33-238f-4d83-adfe-1eaa8df96e90</rd:DataSourceID>
    </DataSource>
  </DataSources>
</Report>

I try to parse and read it using following code:

byte[] fileContent = File.ReadAllBytes(@"path");
            UTF8Encoding unicode = new UTF8Encoding();
            string stringContent = unicode.GetString(fileContent);

            XDocument xml = XDocument.Parse(stringContent);
            XElement dsNode = xml.Root.Element("DataSources");

I can't figure out why is dsNode always null?

+2  A: 

It's a namespace issue... you need to specify the namespace for the DataSources element. Fortunately, LINQ to XML makes this really easy:

XNamespace ns = "http://schemas.microsoft.com/sqlserver/" + 
        "reporting/2008/01/reportdefinition";
XElement dsNode = xml.Root.Element(ns + "DataSources");

Note the xmlns="http://..." part of the root element, which means that element and all elements below it which don't have an explicit namespace inherit that namespace.

Jon Skeet
well I suspected that it was something with the namespaces but I thought that a node <DataSources> does not have a namespace (I though it would be <rd:DataSources> if it had).
agnieszka
It's not rd - it's the *other* namespace declared in the root element. rd is for reportdesigner, the default is for reportdefinition.
Jon Skeet
anyway it is not there explicitly, I just have to know that child elements inherit the namespace
agnieszka
A: 

You are probably missing a namespace reference. Your DataSources will inherit the namespace of the Report node and you will need both the namespace and element local name to generate an XName.

Alternatively you can do the following and skip the namespace check:

XElement dsNode = 
  xml
  .Root
  .DescendantNodes()
  .Where(e => e.Name.LocalName.Equals("DataSources"))
  .First();

This will return the first node where the local name is DataSources. In your example this will be the DataSources element.

Also, your loading of the document is very clumsy. I would suggest the following instead:

XDocument xml = XDocument.Load(File.OpenRead(@"path"));
Rune Grimstad