Click here to Skip to main content
15,881,852 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Input XML File:
XML
<?xml version="1.0" encoding="utf-8" ?>
<TOP>
  <SUB1 name="AB">
    <SUB11 name="CD">
      <SUB111>
        <KV>
          <key>KEY1</key>
          <value>1234</value>
        </KV>
        <KV>
          <key>KEY1</key>
          <value>5678</value>
        </KV>
       </SUB111>
   </SUB11>
    <SUB11 name="CD">
      <SUB111>
        <KV>
          <key>KEY1</key>
          <value>1357</value>
        </KV>
        <KV>
          <key>KEY2</key>
          <value>2468</value>
        </KV>
       </SUB111>
   </SUB11>
</SUB1>
</TOP>


Need to extract all KV elements but distinct within every SUB111. Expected output list of strings:
<key>KEY1</key><value>1234</value>
<key>KEY1</key><value>1357</value>
<key>KEY2</key><value>2468</value>


Note that duplicate KEY1 in first SUB111 is eliminated

Trying something similar to below, but not successful:
C#
IEnumerable<XElement> KVs = null;
KVs = (from sub1 in xDoc.XPathSelectElements("SUB1")
       where (string)sub1.Attribute("name").Value == "AB"
       from sub11 in sub1.Elements("SUB11")
       where (string)sub11.Attribute("name").Value == "CD"
       select sub11).SelectMany(sub111 => sub111.Elements("SUB111").Elements("KV")).ToList();


Thanks in advance for your help!
Regards
S. Vikram
Posted
Updated 3-Nov-14 21:33pm
v3

C#
string xml = @"<?xml version=""1.0"" encoding=""utf-8"" ?>
<TOP>
<SUB1 name=""AB"">
    <SUB11 name=""CD"">
    <SUB111>
        <KV>
        <key>KEY1</key>
        <value>1234</value>
        </KV>
        <KV>
        <key>KEY1</key>
        <value>5678</value>
        </KV>
    </SUB111>
</SUB11>
    <SUB11 name=""CD"">
    <SUB111>
        <KV>
        <key>KEY1</key>
        <value>1357</value>
        </KV>
        <KV>
        <key>KEY2</key>
        <value>2468</value>
        </KV>
    </SUB111>
</SUB11>
</SUB1>
</TOP>";
XDocument doc = XDocument.Parse(xml);
var items = doc.Root.Descendants("SUB111")
                .SelectMany(s=>s.Descendants("KV")
                .GroupBy(x=>(string)x.Element("key"))
                .Select(g=>g.First()))
                .ToList();


You may need to add your where conditions but most important thing is you can group by key value and select the first item of the group, that will remove the duplicates.
 
Share this answer
 
v4
Comments
Erpizn_13 4-Nov-14 3:47am    
Quite close, got 2 elements in the list, one with
KEY1,1234 (as required)

and one more with
KEY1,1357
KEY2,2468
together.

Need a single list with these 3 elements only :)
Thanks!
DamithSL 4-Nov-14 3:51am    
change Select to SelectMany, check my updated answer
Erpizn_13 4-Nov-14 3:53am    
Awesome! Thanks a lot!
BillWoodruff 4-Nov-14 4:10am    
Hi Damith, Your code will not cause an error, but, unless you change 'SUB111 to 'sub111, and 'KV to 'kv, in your Linq statement, it will return an empty result.

Good response !
DamithSL 4-Nov-14 4:24am    
Bill, XML string case changed to lowercase when auto formatting in the code project editor, i think now it is fine. thanks
Use Distinct() after selectMany().
 
Share this answer
 
Comments
Erpizn_13 4-Nov-14 3:22am    
Tried this, but did not work :( Somehow need to use 'group by' I feel, but not getting how exactly!

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900