Create XML Files with All Combination of Values Attribute

sample.xml (source file)<settings>
    <param name="size" value="" values="1,2" />
    <custom>
      <param name="color" value="" values="red,green" />
    </custom>
</settings>

Desired XML files:

sample_size=1_color=red.xml<settings>
  <param name="size" value="1" />
  <custom>
    <param name="color" value="red" />
  </custom>
</settings>
sample_size=1_color=green.xml<settings>
  <param name="size" value="1" />
  <custom>
    <param name="color" value="green" />
  </custom>
</settings>
sample_size=2_color=red.xml<settings>
  <param name="size" value="2" />
  <custom>
    <param name="color" value="red" />
  </custom>
</settings>
sample_size=2_color=green.xml<settings>
  <param name="size" value="2" />
  <custom>
    <param name="color" value="green" />
  </custom>
</settings>

Bit of coding:

C# codepublic class XmlNodeInput
{
    public XmlNode XmlNode { get; set; }
    public string[] Values { get; set; }
}

public class XmlNodeOutput
{
    public XmlNode XmlNode { get; set; }
    public string Value { get; set; }
}

public class XmlManager
{
    public XmlManager(string xmlFilePath)
    {
        XmlDocument doc = new XmlDocument();
        doc.Load(xmlFilePath);

        List<XmlNodeInput> input = new List<XmlNodeInput>();
        foreach (XmlNode node in doc.SelectNodes("//node()[@value and @values]"))
        {
            XmlAttribute valuesAttr = node.Attributes["values"];
            string[] values = valuesAttr.Value.Split(',').Select(v => v.Trim()).ToArray();
            input.Add(new XmlNodeInput
            {
                XmlNode = node,
                Values = values
            });
        }

        List<List<XmlNodeOutput>> fileNodes = Combine(input);

        foreach (List<XmlNodeOutput> nodeOutputs in fileNodes)
        {
            StringBuilder fileName = new StringBuilder(Path.Combine(Path.GetDirectoryName(xmlFilePath), Path.GetFileNameWithoutExtension(xmlFilePath)));
            foreach (XmlNodeOutput xmlNodeOutput in nodeOutputs)
            {
                Console.Write(xmlNodeOutput.Value);
                fileName.AppendFormat("_{0}={1}", xmlNodeOutput.XmlNode.Attributes["name"].Value, xmlNodeOutput.Value);

                ((XmlElement)xmlNodeOutput.XmlNode).RemoveAttribute("values");
                xmlNodeOutput.XmlNode.Attributes["value"].Value = xmlNodeOutput.Value;
            }
            fileName.Append(".xml");

            Console.WriteLine();
            doc.Save(fileName.ToString());
        }
    }

    private List<List<XmlNodeOutput>> Combine(List<XmlNodeInput> input)
    {
        List<List<XmlNodeOutput>> fileNodes = new List<List<XmlNodeOutput>>();
        Combine(input, new XmlNodeOutput[input.Count()], 0, fileNodes);

        return fileNodes;
    }

    private void Combine(List<XmlNodeInput> input, XmlNodeOutput[] current, int inputIndex, List<List<XmlNodeOutput>> fileNodes)
    {
        if (inputIndex == input.Count())
        {
            fileNodes.Add(current.ToList());
        }
        else
        {
            for (int valueIndex = 0; valueIndex < input[inputIndex].Values.Count(); valueIndex++)
            {
                current[inputIndex] = new XmlNodeOutput
                {
                    XmlNode = input[inputIndex].XmlNode,
                    Value = input[inputIndex].Values[valueIndex]
                };
                Combine(input, current, inputIndex + 1, fileNodes);
            }
        }
    }
}


Back