ist_lion
ist_lion

Reputation: 3209

XDocument AncestorAndSelf

I currently have an XML Structure that looks something like this

<Parent>
 <Info>
   <Info-Data></Info-Data>
   <Info-Data2></Info-Data2>
 </Info>
 <Message>
   <Foo></Foo>
   <Bar></Bar>
 </Message>
 <Message>
   <Foo/>
   <Bar/>
 </Message>
</Parent>

What I'm trying to accomplish is split each Message into it's own unique XDocument. I want it to be

<Parent>
 <Info />
 <Message />
</Parent> 

I tried to do the following.

XDocument xDoc = XDocument.Parse(myXMLString);

IEnumerable<XElement> elements = xDoc.Descendants(xDoc.Root.Name.NameSpace + "Message");

foreach(XElement element in elements)
{
  XDocument newDoc = XDocument.Parse(element.ToString());
}

Obviously this only gets me everything from Message and below. I tried using Ancestors and AncestorsAndSelf but they always include BOTH Messages. Is there a different call I should be making?

Upvotes: 0

Views: 393

Answers (1)

Jon Skeet
Jon Skeet

Reputation: 1501916

If your format is fixed like this, it's not so bad:

foreach(XElement element in elements)
{
    XDocument newDoc = new XDocument
        (new XElement(xDoc.Root.Name,
            xDoc.Root.Element("Info"),
            element));
    // ...
}

It's not great, but it's not horrendous. An alternative is to clone the original document, remove all the Message elements, then repeatedly clone the "gutted" version and add one element at a time to the new clone:

XDocument gutted = new XDocument(xDoc);
gutted.Descendants(xDoc.Root.Name.Namespace + "Message").Remove();

foreach(XElement element in elements)
{
    XDocument newDoc = new XDocument(gutted);
    newDoc.Root.Add(element);
    // ...
}

Upvotes: 1

Related Questions