gymcode
gymcode

Reputation: 4623

How To Store a XML section by the tag

I would like to store the original section of a XML string, split by the base on each root element of <ROW NUMBER="1">, and assign to a string.

May I know how can it be done?

<?xml version="1.0"?>
<ROWS>
  <ROW NUMBER="1">
    <PersonID>P1</PersonID>
    <PersonName>JAMES</PersonName>
  </ROW>
  <ROW NUMBER="2">
    <PersonID>P2</PersonID>
    <PersonName>MARY</PersonName>
  </ROW>
</ROWS>

Expected result:

string person1 = "<PersonID>P1</PersonID><PersonName>JAMES</PersonName>"

string person2 = "<PersonID>P2</PersonID><PersonName>MARY</PersonName>"

Thank you.

Upvotes: 0

Views: 46

Answers (2)

jdweng
jdweng

Reputation: 34429

I usually use a dictionary like this :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;

namespace ConsoleApplication1
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            XDocument doc = XDocument.Load(FILENAME);

            Dictionary<string, List<XElement>> dict = doc.Descendants("ROW")
                .GroupBy(x => (string)x.Element("PersonID"), y => y)
                .ToDictionary(x => x.Key, y => y.Descendants().ToList());

 
        }
    }
}

Upvotes: 1

ProgrammingLlama
ProgrammingLlama

Reputation: 38777

This is relatively trivial:

var xml = "<?xml version=\"1.0\"?><ROWS>  <ROW NUMBER=\"1\">    <PersonID>P1</PersonID>    <PersonName>JAMES</PersonName>  </ROW>  <ROW NUMBER=\"2\">    <PersonID>P2</PersonID>    <PersonName>MARY</PersonName>  </ROW></ROWS>";

// Load XML into XmlDocument
var doc = new XmlDocument();
doc.LoadXml(xml);

// Select the ROW nodes
var nodes = doc.SelectNodes("/ROWS/ROW");

// Select the value of the NUMBER attribue and the InnerXML into an anonymous object
// and convert into a dictionary with the key personX (where X is the value of the NUMBER attribute)
var dictionary = nodes
    .Cast<XmlNode>()
    .Select(n => new { Row = n.Attributes["NUMBER"].Value, Xml = n.InnerXml })
    .ToDictionary(r => $"person{r.Row}", r => r.Xml);

Disclaimer: the ToDictionary part will fail if a duplicate NUMBER attribute value exists (DuplicateKeyException). You might need to write some code to handle it.

Upvotes: 0

Related Questions