Sahil Gupta
Sahil Gupta

Reputation: 295

How to remove duplicate nodes in an XML document in C#?

I want to remove all the transactions that have say "SetActiveLocale" and have the value of "en", except for the very first SetActiveLocale Transaction. I am using an XML document to store this whole string file.

<bmtactionlog>
    <transaction saved="false" seq="1" timestamp="20130621143502322">
            <action seq="1" type="SetActiveLocale">
                <inputparams>
                    <param seq="1" type="i18nstring">
                        <value>en</value>
                    </param>
                </inputparams>
                <domchanges/>
                <result success="t">
                    <outputparams/>
                </result>
            </action>
        </transaction>
        <transaction saved="true" seq="2" timestamp="20130621143502322">
            <action seq="1" type="Modify">
                <inputparams>
                    <param seq="1" type="handle">
                        <mappingpath>shortcut/description</mappingpath>
                        <value>/O/description[0]/O/[Employee expense].[Account]</value>
                    </param>
                    <param seq="2" type="i18nstring">
                        <value>2:34</value>
                    </param>
                </inputparams>
                <domchanges/>
                <result success="t">
                    <outputparams/>
                </result>
            </action>
        </transaction>
        <transaction saved="false" seq="1" timestamp="20130621143502327">
            <action seq="3" type="SetActiveLocale">
                <inputparams>
                    <param seq="1" type="i18nstring">
                        <value>en</value>
                    </param>
                </inputparams>
                <domchanges/>
                <result success="t">
                    <outputparams/>
                </result>
            </action>
        </transaction>
        <transaction saved="true" seq="4" timestamp="20130621143502327">
            <action seq="1" type="Modify">
                <inputparams>
                    <param seq="1" type="handle">
                        <mappingpath>shortcut/description</mappingpath>
                        <value>/O/description[0]/O/[Employee expense].[Employee (by manager)]</value>
                    </param>
                    <param seq="2" type="i18nstring">
                        <value>2:34</value>
                    </param>
                </inputparams>
                <domchanges/>
                <result success="t">
                    <outputparams/>
                </result>
            </action>
        </transaction>
        <transaction saved="false" seq="1" timestamp="20130621143502327">
            <action seq="5" type="SetActiveLocale">
                <inputparams>
                    <param seq="1" type="i18nstring">
                        <value>en</value>
                    </param>
                </inputparams>
                <domchanges/>
                <result success="t">
                    <outputparams/>
                </result>
            </action>
        </transaction>
        <transaction saved="true" seq="6" timestamp="20130621143502327">
            <action seq="1" type="Modify">
                <inputparams>
                    <param seq="1" type="handle">
                        <mappingpath>shortcut/description</mappingpath>
                        <value>/O/description[0]/O/[Employee expense].[Employee (by organization)]</value>
                    </param>
                    <param seq="2" type="i18nstring">
                        <value>2:34</value>
                    </param>
                </inputparams>
                <domchanges/>
                <result success="t">
                    <outputparams/>
                </result>
            </action>
        </transaction>
        <transaction saved="false" seq="1" timestamp="20130621143502327">
            <action seq="7" type="SetActiveLocale">
                <inputparams>
                    <param seq="1" type="i18nstring">
                        <value>en</value>
                    </param>
                </inputparams>
                <domchanges/>
                <result success="t">
                    <outputparams/>
                </result>
            </action>
        </transaction>
        <transaction saved="true" seq="8" timestamp="20130621143502327">
            <action seq="1" type="Modify">
                <inputparams>
                    <param seq="1" type="handle">
                        <mappingpath>shortcut/description</mappingpath>
                        <value>/O/description[0]/O/[Employee expense].[Employee (by position)]</value>
                    </param>
                    <param seq="2" type="i18nstring">
                        <value>2:34</value>
                    </param>
                </inputparams>
                <domchanges/>
                <result success="t">
                    <outputparams/>
                </result>
            </action>
        </transaction>
        <transaction saved="false" seq="1" timestamp="20130621143640438">
            <action seq="1" type="SetActiveLocale">
                <inputparams>
                    <param seq="1" type="i18nstring">
                        <value>en</value>
                    </param>
                </inputparams>
                <domchanges/>
                <result success="t">
                    <outputparams/>
                </result>
            </action>
        </transaction>
        <transaction saved="true" seq="10" timestamp="20130621143640438">
            <action seq="1" type="SetSecurityViewAccess">
                <inputparams>
                    <param seq="1" type="handle">
                        <mappingpath>securityView</mappingpath>
                        <value>[].[securityViews].[GO Data Warehouse (analysis)]</value>
                    </param>
                    <param seq="2" type="integer">
                        <value>1</value>
                    </param>
                    <param seq="3" type="cclnode">
                        <value>
                            <![CDATA[<securityObjects/>]]></value>
                    </param>
                </inputparams>
                <domchanges/>
                <result success="t">
                    <outputparams/>
                </result>
            </action>
        </transaction>
        <transaction saved="true" seq="11" timestamp="20130621143640439">
            <action seq="1" type="SetSecurityViewAccess">
                <inputparams>
                    <param seq="1" type="handle">
                        <mappingpath>package</mappingpath>
                        <value>[].[packages].[GO Data Warehouse (analysis)]</value>
                    </param>
                    <param seq="2" type="integer">
                        <value>1</value>
                    </param>
                    <param seq="3" type="cclnode">
                        <value>
                            <![CDATA[<securityObjects/>]]></value>
                    </param>
                </inputparams>
                <domchanges/>
                <result success="t">
                    <outputparams/>
                </result>
            </action>
        </transaction>
        <transaction saved="true" seq="12" timestamp="20130621143640439">
            <action seq="1" type="Publish">
                <inputparams>
                    <param seq="1" type="handle">
                        <mappingpath>package</mappingpath>
                        <value>[].[packages].[GO Data Warehouse (analysis)]</value>
                    </param>
                    <param seq="2" type="integer">
                        <value>2</value>
                    </param>
                    <param seq="3" type="i18nstring">
                        <value>/content/folder[@name=&apos;Sahil&apos;]</value>
                    </param>
                    <param seq="4" type="i18nstring">
                        <value>GO Data Warehouse (analysis)</value>
                    </param>
                    <param seq="5" type="integer">
                        <value>1</value>
                    </param>
                    <param seq="6" type="integer">
                        <value>1</value>
                    </param>
                    <param seq="7" type="integer">
                        <value>-1</value>
                    </param>
                </inputparams>
                <domchanges/>
                <result success="t">
                    <outputparams/>
                </result>
            </action>
        </transaction>
    </bmtactionlog>

Upvotes: 1

Views: 3734

Answers (2)

Jetti
Jetti

Reputation: 2458

Here is a concise way to do what you are looking for:

XmlNodeList nodes = doc.SelectNodes("//bmtactionlog/transaction/action[@type='SetActiveLocale']");
XmlNode actionNode = doc.SelectSingleNode("//bmtactionlog");
for(int i = 1; i < nodes.Count; i++)
{
    actionNode.RemoveChild(nodes[i]);
}

This will get the all of the transaction nodes that are of type SetActiveLocale and then remove all but the first node.

Upvotes: 1

Jan Berktold
Jan Berktold

Reputation: 951

Here, I've wrote a little function for you.

It's quite ugly, but it does get the job done perfectly.

        public static void RemoveDuplicates(string filePath)
    {
        XmlDocument reader = new XmlDocument();
        reader.Load(filePath);

        bool foundApplicable = false;
        ArrayList removeNodes = new ArrayList();
        foreach(XmlNode node in reader.GetElementsByTagName("transaction"))
        {
            if (node.FirstChild != null && node.FirstChild.Attributes["type"].Value == "SetActiveLocale")
            {
                if (node.SelectSingleNode("action/inputparams/param") != null && node.SelectSingleNode("action/inputparams/param").InnerText == "en")
                {
                    if (foundApplicable)
                    {
                        // I have to use a list because foreach breaks if I remove a node while the loop is working
                        removeNodes.Add(node);
                    }
                    else
                        foundApplicable = true;
                }
            }
        }
        foreach (XmlNode node in removeNodes)
        {
            node.ParentNode.RemoveChild(node);
        }
        reader.Save(filePath);
    }

Upvotes: 1

Related Questions