0

I'm looking to split an XML document into a list of strings but I'm totally at a loss.

<RISKCALC-OUT>
  <AUTHENTICATION>
    <USERID></USERID>
  </AUTHENTICATION>
  <OPERATION-LIST>
    <OPERATION MODEL="PRV" SUBMODEL="GBR40EDF" VERSION="4.0" FUNCTION="EDFCLC" TARGET="New Platform">
      .......
    </OPERATION>
    <OPERATION MODEL="PRV" SUBMODEL="GBR40EDF" VERSION="4.0" FUNCTION="EDFCLC" TARGET="New Platform">
      .....
    </OPERATION>
  </OPERATION-LIST>
</RISKCALC-OUT>

I'm trying to split this file into strings, so that everything below the first operation node is in one string, and then everything below the second operation node is in a second string.

I've been playing around with XmlNodeLists but I haven't got anywhere. I don't need a total answer, just how to separate them ready to put in to separate strings.

Thanks for your help.

Robert Woods
  • 350
  • 1
  • 6
  • 17
  • 2
    Please show an example result, so it 's not ambiguous and people don't loose searching in the dark. Are these the .... that you expect to see in a first string and same in second string ? – Emmanuel DURIN Nov 03 '15 at 13:23
  • You *don't* need to separate anything, you need to *select* the Operation nodes, using XPath or LINQ to XML. You can use the `//OPERATION` XPath expression to return all operation nodes, eg with [XmlDocument.SelectNodes](https://msdn.microsoft.com/en-us/library/hcebdtae(v=vs.110).aspx). If you use XDocument instead you can type a LINQ query instead of XPath – Panagiotis Kanavos Nov 03 '15 at 13:31
  • Sorry, each operation looks like this: https://gist.github.com/robbiewoods05/0a50ff5d1905e8f1ff83 That's exactly what I'd like each string to look like. – Robert Woods Nov 03 '15 at 13:31
  • Look at treeview example : http://stackoverflow.com/questions/28976601/recursion-parsing-xml-file-with-attributes-into-treeview-c-sharp – jdweng Nov 03 '15 at 15:04

2 Answers2

3

I would use LinQ to Xml.
Maintenance is easier.

XElement xmla = XElement.Load("input.xml");
var results = from operationList in xmla.Descendants("OPERATION")
                select operationList.Value;
foreach (var result in results)
{
    Console.WriteLine(result);
}

EDIT to have the best of both worlds
(Actually there are three worlds here: Object/String and XML)

A class to hold the data :

class Operation
{
    public String Model { get; set; }
    public String SubModel { get; set; }
    // and so on ...

    public String TagContent { get; set; }
    public String FullTag{ get; set; }
}

Make the linq query :

XElement xmla = XElement.Load("input.xml");
var operations = from operation in xmla.Descendants("OPERATION")
                    select new Operation
                    {
                        Model = operation.Attribute("MODEL").Value,
                        SubModel = operation.Attribute("SUBMODEL").Value,
                        TagContent = operation.Value,
                        FullTag = operation.ToString(),

                    };
foreach (var operation in operations)
{
    Console.WriteLine(operation.Model + " - " + operation.SubModel+ " - " + operation.TagContent " - " + operation.FullTag);
}

Regards

Emmanuel DURIN
  • 4,803
  • 2
  • 28
  • 53
2

You can use LINQ to XML like this:

static void Main(string[] args)
{
    string path = "XMLFile1.xml";
    XDocument xdoc = XDocument.Load(path);
    var ops = xdoc.Descendants("OPERATION")
        .Elements()
        .Select(n => n.ToString())
        .ToList<string>();

    ops.ForEach(s => Console.WriteLine(s));
}

I used this sample XML (added random stuff for testing purposes):

<RISKCALC-OUT>
  <AUTHENTICATION>
    <USERID></USERID>
  </AUTHENTICATION>
  <OPERATION-LIST>
    <OPERATION MODEL="PRV" SUBMODEL="GBR40EDF" VERSION="4.0" FUNCTION="EDFCLC" TARGET="New Platform">
      <SUBNODES ID="1">
        <ANOTHER ID="56"></ANOTHER>
      </SUBNODES>
    </OPERATION>
    <OPERATION MODEL="PRV" SUBMODEL="GBR40EDF" VERSION="4.0" FUNCTION="EDFCLC" TARGET="New Platform">
      <SUBNODES ID="1">
        <ANOTHER ID="65"></ANOTHER>
      </SUBNODES>
    </OPERATION>
  </OPERATION-LIST>
</RISKCALC-OUT>

and got this output with the above code:

<SUBNODES ID="1">
  <ANOTHER ID="56"></ANOTHER>
</SUBNODES>
<SUBNODES ID="1">
  <ANOTHER ID="65"></ANOTHER>
</SUBNODES>

To keep the OPERATION nodes you can remove Elements() like this:

var ops = xdoc.Descendants("OPERATION")
            .Select(n => n.ToString())
            .ToList<string>();

which would produce

<OPERATION MODEL="PRV" SUBMODEL="GBR40EDF" VERSION="4.0" FUNCTION="EDFCLC" TARGE
T="New Platform">
  <SUBNODES ID="1">
    <ANOTHER ID="56"></ANOTHER>
  </SUBNODES>
</OPERATION>
<OPERATION MODEL="PRV" SUBMODEL="GBR40EDF" VERSION="4.0" FUNCTION="EDFCLC" TARGE
T="New Platform">
  <SUBNODES ID="1">
    <ANOTHER ID="65"></ANOTHER>
  </SUBNODES>
</OPERATION>
Volkan Paksoy
  • 6,727
  • 5
  • 29
  • 40