Bill Roberts
Bill Roberts

Reputation: 1171

Using LINQ to parse one XML file into multiple files based on child element value

I have an XML file and I want to split it into multiple XML files based in VIEWNAME.

Per the sample below, there are three VIEWNAME values, and for each, there are also VIEWPANE elements and VIEWCOLUMN elements.

Using LINQ, my code thus far can save files that only encompass the VIEWNAME nodes:

static void VisualViews( XDocument xdoc)
{
  var baseFolder = Prep(FolderRDS, "VisualViews");

  var viewNames = xdoc.Element("VisualModelDS").Elements("viewname");

  foreach (var viewName in viewNames)
  {
    var name = viewName.Element("viewname").Value;
    viewName.Save(string.Format(@"{0}{1}.xml", baseFolder, name));
  }
}

I'm looking for help to also include the other nodes that have a corresponding VIEWNAME value. I think what I want is to group all parent/child elements that have the same child VIEWNAME element, and then save each group of elements to its own XML file, based on the VIEWNAME element value.

The XML below would parse into 2 files, and I've embedded a hard return to differentiate which elements would go into which file.

So all said, every parent element has a child VIEWNAME element from which to group by.

XML EDITED TO EMBED SPACES INTO ELEMENT VALUES

<?xml version="1.0" standalone="yes"?>
<VisualModelDS>
  <viewname>
    <viewname>A B C</viewname>
  </viewname>
  <viewpane>
    <viewname>A B C</viewname>
    <viewpane>ALPHA</viewpane>
  </viewpane>
  <viewcolumn>
    <viewname>A B C</viewname>
    <viewpane>ALPHA</viewpane>
    <viewcolumn>Apples</viewcolumn>
  </viewcolumn>
  <viewcolumn>
    <viewname>A B C</viewname>
    <viewpane>ALPHA</viewpane>
    <viewcolumn>Oranges</viewcolumn>
  </viewcolumn>

  <viewname>
    <viewname>X Y Z</viewname>
  </viewname>
  <viewpane>
    <viewname>X Y Z</viewname>
    <viewpane>CAPPA</viewpane>
  </viewpane>
  <viewcolumn>
    <viewname>X Y Z</viewname>
    <viewpane>CAPPA</viewpane>
    <viewcolumn>Macadema</viewcolumn>
  </viewcolumn>
  <viewcolumn>
    <viewname>X Y Z</viewname>
    <viewpane>CAPPA</viewpane>
    <viewcolumn>Pecan</viewcolumn>
  </viewcolumn>
  <viewpane>
    <viewname>X Y Z</viewname>
    <viewpane>OMEGA</viewpane>
  </viewpane>
  <viewcolumn>
    <viewname>X Y Z</viewname>
    <viewpane>OMEGA</viewpane>
    <viewcolumn>Peanut</viewcolumn>
  </viewcolumn>
</VisualModelDS>

Upvotes: 0

Views: 118

Answers (1)

Alexander Petrov
Alexander Petrov

Reputation: 14251

var viewNames = xdoc.Root.Elements("viewname").Elements("viewname");

foreach (var viewName in viewNames)
{
    var group = new XElement(viewName.Value.Replace(" ", ""),
        xdoc.Root.Elements().Where(elem => elem.Element("viewname").Value == viewName.Value));

    group.Save(viewName.Value + ".txt");
}

Upvotes: 1

Related Questions