Click here to Skip to main content
15,891,738 members
Please Sign up or sign in to vote.
2.50/5 (2 votes)
See more:
Hi , i want this xml file Element <common name="MAN.."> to change position as last Element using Linq C#, i have this XML

XML
<?xml version="1.0" encoding="utf-8"?>
<ROOT>
  <Local Name="Require" >
     </Local>
  <Host Name="Stills" >
     </Host>
    <Common Name="MAN"  ID="188b655f-fc47-43af-acd7-99d0764cca33">
                <Common Name="System" ID="188b655f-fc47-43af-acd7-99d0764cca3">
                  </Common>
                <Common Name="System"  ID="080f8b14-22a4-46d9-ac3f-57e6fcc87e04">
                  </Common>
    </Common>
</ROOT>



i want like this finally

XML
<?xml version="1.0" encoding="utf-8"?>
<ROOT>
  <Local Name="Require" >
     </Local>
  <Host Name="Stills" >
     </Host>
                <Common Name="System" ID="188b655f-fc47-43af-acd7-99d0764cca3">
                  </Common>
                <Common Name="System"  ID="080f8b14-22a4-46d9-ac3f-57e6fcc87e04">
                  </Common>

                   <Common Name="MAN"  ID="188b655f-fc47-43af-acd7-99d0764cca33">
                   </Common>
</ROOT>
Posted

Disreguard my last solution as I did not read your XML properly. You are modifying the heirarchy of the tree, so you can use Decentants to seek it out. After seeking them you can place them in a duplicate XDocument.
After that you can put in the nodes they 'were' in minus the nodes that have been moved.

Bellow I have broken it down into 2 methods. One that reads the data in, and one that handles your reordering.

C#
private void ReadXML()
{
    _rawXML = XDocument.Load(PATH_INPUT);
            
    //fill our duplicate
    _sortedXML = XDocument.Load(PATH_INPUT);

    //Remove the data we will sort on so it can be repopulated
    var nodesThatWillBeRepopulated = _sortedXML.Root.Elements(ELEMENT_SORT).ToList();
    foreach (var node in nodesThatWillBeRepopulated)
    {
        node.Remove();
    }
}


The first thing we do is get a compilation of all the nodes to be moved (with "System" in the "Name" field of element type "Common". Then we also grab the ones that are to not be moved but have the 'moved' ones removed from their node.

The loops do the actual work.

C#
private void SortXML()
{
    var moveThese = _rawXML.Root.Descendants(ELEMENT_SORT).Where(node => node.Attribute(ATTRIBUTE_COMP) != null &&  string.Equals(node.Attribute(ATTRIBUTE_COMP).Value, ATTRIBUTE_MOVE, StringComparison.CurrentCultureIgnoreCase));
    var addTheseBackInLast = _rawXML.Root.Descendants(ELEMENT_SORT).Where(node => node.Attribute(ATTRIBUTE_COMP) != null && string.Equals(node.Attribute(ATTRIBUTE_COMP).Value, ATTRBITE_SEEK, StringComparison.CurrentCultureIgnoreCase));


    //Now add copied nodes to the 'duplicate' document at the desired position in the tree (one bellow the root)
    foreach (var node in moveThese)
    {
        _sortedXML.Root.Add(new XElement(node));
    }

    //Now add the node with out the moved contents
    foreach (var node in addTheseBackInLast)
    {
        //First remove the data
        var removeThese = node.Descendants(ELEMENT_SORT).Where(element => element.Attribute(ATTRIBUTE_COMP) != null &&  string.Equals(element.Attribute(ATTRIBUTE_COMP).Value, ATTRIBUTE_MOVE, StringComparison.CurrentCultureIgnoreCase)).ToList();
        foreach (var removeThis in removeThese)
        {
            removeThis.Remove();
        }

        //Now add it in
        _sortedXML.Root.Add(new XElement(node));
    }

    //_sortedXML is now in the form you need, so save send or whatever
}



And here are the constants I was using (hardcoded to your XML data)
C#
private const string ATTRIBUTE_MOVE = "System";
private const string ELEMENT_SORT = "Common";
private const string ATTRBITE_SEEK = "Man";
private const string ATTRIBUTE_COMP = "Name";
private XDocument _rawXML;
private XDocument _sortedXML;


Let me know if you do not understand something.
 
Share this answer
 
Comments
getanswer 5-Feb-12 7:19am    
Hii Collin , thank you very much for your great answer, its nice code,i got it.
[no name] 6-Feb-12 10:03am    
You are welcome :-)
Not sure why you tagged this WPF (this is just XML and LINQ)

You can use the XDocument[^] to read the data in. Then create a 'duplicate' with out the elements you plan to move (get the root 'local' and 'host' elements as you have them).

After you have done that you can query out all of the elements you want to change the order on.
var reorderThese = xDoc.Elements("Common")

Now that you have the elements you just need to sort them. I would recomend implimenting the IComparer[^] interface and use that comparitor. I can only assume you want the one element because it is a "Man".. Maybe you want to swap because it is the first index (that is a bit odd though, seems somewhat arbitrary then). By building a sorter you will handle the needs if sorting becomes more complicated etc.

You then need only call the sort method and use your implimentation of IComparer<T>.
reorderThese.Sort(new CustomerSorter())

Now that you have the elements sorted just put them in your duplicate xDoc.
duplicate.Root.Add(reorderThese). Now your 'duplciate' XDocument is what you want so you can overwrite the original with that data.

[Edit] Oh looks like you are actually chaning the heirarchy. Let me ponder.
 
Share this answer
 
v2
Comments
getanswer 3-Feb-12 4:21am    
Hi, Collin thanks for Reply , can you please give some more explanation because am new ti LINQ , how to do by step by step, thanks
[no name] 3-Feb-12 10:00am    
Well I kinda of gace you step by step. I will put it in more of a code block so it is real clear. Check back in 10 min after this comment.
getanswer 3-Feb-12 10:12am    
Thank you very much collin
[no name] 3-Feb-12 11:18am    
Just realized you are not just sorting but actually changed the heirachy of the tree. Disreguard what I originally said. I will try and come up with something though.
getanswer 3-Feb-12 11:24am    
exactly, i want to change Parent element as individul element and want to save as last element,waiting for reply

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