如何在C#中删除XML文档中的重复节点
本文关键字:节点 文档 删除 XML | 更新日期: 2023-09-27 18:19:37
我想删除所有具有"SetActiveLocale"和值为"en"的事务,除了第一个SetActiveLocaleTransaction。我正在使用一个XML文档来存储整个字符串文件。
<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='Sahil']</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>
这里有一个简洁的方法来完成您想要的任务:
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]);
}
这将获得所有类型为SetActiveLocale的事务节点,然后删除除第一个节点之外的所有节点。
在这里,我为您编写了一个小函数。
它很难看,但它确实完美地完成了任务。
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);
}