2

Given the following XDocument, initialized into variable xDoc:

<Report xmlns="http://schemas.microsoft.com/sqlserver/reporting/2010/01/reportdefinition">
  <ReportSection>
    <Width />
    <Page>
  </ReportSections>
</Report>

I have a template embedded in an XML file (let's call it body.xml):

<Body xmlns="http://schemas.microsoft.com/sqlserver/reporting/2010/01/reportdefinition">
  <ReportItems />        
  <Height />
  <Style />
</Body>

Which I would like to put as a child of <ReportSection>. Problem is if add it through XElement.Parse(body.xml), it keeps the namespace, even though I would think namespace should be removed (no point in duplicating itself - already declared on the parent). If I don't specify namespace, it puts an empty namespace instead, so it becomes <Body xmlns="">.

Is there a way to properly merge XElement into XDocument? I would like to get the following output after xDoc.Root.Element("ReportSection").AddFirst(XElement):

<Report xmlns="http://schemas.microsoft.com/sqlserver/reporting/2010/01/reportdefinition">
  <ReportSection>
    <Body>
      <ReportItems />        
      <Height />
      <Style />
    </Body>
    <Width />
    <Page>
  </ReportSections>
</Report>
Victor Zakharov
  • 25,801
  • 18
  • 85
  • 151
  • Check this out: http://stackoverflow.com/questions/4985974/xelement-namespaces-how-to – Codeman Nov 28 '12 at 20:44
  • 1
    @Pheonixblade9: Unfortunately, in my case XML is not created by code, as it is done in dozens of examples on StackOverflow, including the one you mentioned. It is not a problem in creating an XElement from scratch and merging it into the XDocument. It's about XElement.Parse returning a tree of nodes. – Victor Zakharov Nov 28 '12 at 20:58

1 Answers1

6

I'm not sure why this is happening, but removing the xmlns attribute from the body element seems to work:

var report = XDocument.Parse(
@"<Report xmlns=""http://schemas.microsoft.com/sqlserver/reporting/2010/01/reportdefinition"">
  <ReportSection>
    <Width />
    <Page />
  </ReportSection>
</Report>");

var body = XElement.Parse(
@"<Body xmlns=""http://schemas.microsoft.com/sqlserver/reporting/2010/01/reportdefinition"">
  <ReportItems />        
  <Height />
  <Style />
</Body>");

XNamespace ns = report.Root.Name.Namespace;
if (body.GetDefaultNamespace() == ns)
{
   body.Attribute("xmlns").Remove();
}

var node = report.Root.Element(ns + "ReportSection");
node.AddFirst(body);
Richard Deeming
  • 29,830
  • 10
  • 79
  • 151
  • Very interesting. Indeed, removing `xmlns` attribute manually makes it work. While not having it on `body` in the first place does not work, although both options should have resulted in the same effect. Thanks for digging it up. +1 – Victor Zakharov Nov 28 '12 at 21:22