Xdocument Xd(从xml文件映射):
<pfsense>
<nat>
<outbound>
<mode>advanced</mode>
</outbound>
<rule>
<source>
<any />
</source>
<destination>
<network>wanip</network>
<port>63350</port>
</destination>
<protocol>tcp</protocol>
<target>10.100.100.15</target>
<local-port>11</local-port>
<interface>wan</interface>
<descr><![CDATA[delete this]]></descr>
<associated-rule-id />
</rule>
<rule>
<source>
<any />
</source>
<destination>
<network>wanip</network>
<port>63350</port>
</destination>
<protocol>tcp</protocol>
<target>10.100.100.11</target>
<local-port>11</local-port>
<interface>wan</interface>
<descr><![CDATA[don't delete this]]></descr>
<associated-rule-id />
</rule>
</nat>
</pfsense>
我想只删除具有以下描述的规则元素:
<descr><![CDATA[delete this]]></descr>
预期结果是相同的XDocument(Xd),没有将要删除的条件的XElement。我试过这个:
XElement ruleToDelete = null;
foreach (var x in Xd.Root.Element("nat").Elements("rule"))
{
if (x.Element("descr")!= null && x.Element("descr").Value == ruleDescription)
{
ruleToDelete = x;
break;
}
}
if (ruleToDelete != null)
{
ruleToDelete.Remove();
//But Xd is the same as before...
}
但是,我希望Xd受到影响......
答案 0 :(得分:0)
这样的事情应该有效:
xd.Element("pfsense").Elements("nat").Elements("rule").Elements("descr").Where(x => x.Value == "delete this").Remove();
答案 1 :(得分:0)
一个简单的天真解决方案
var elements = Xd.XPathSelectElements("/pfsense/nat//rule[descr/text() = 'delete this']");
elements.Remove();
答案 2 :(得分:0)
使用Where
和Any
之类的:
Xd.Root.Element("nat").Elements("rule").Where
(x => x.Elements("descr").Any(t => t.Value == ruleDescription)).Remove();
并验证结果:
Assert.IsFalse(Xd.Root.Element("nat").Elements
("rule").Any(x => x.Elements("descr").Any(t => t.Value == ruleDescription)));
答案 3 :(得分:0)
这对你有用;
你可能知道Element有一个级别。如果你想做这样的事情,你最好使用后代。其他要注意的是使用“Equal”运算符。您可以使用包含,但使用“删除”和“不删除”等值时风险太大。另请注意,即使您有CDATA,它们也不会出现在“值”中。
class Program
{
static void Main(string[] args)
{
var xdoc = XDocument.Load(@"C:\Xd.xml");
Console.WriteLine("--------------------");
Console.WriteLine("BEFORE");
Console.WriteLine("--------------------");
Console.WriteLine(xdoc.ToString());
xdoc.Descendants().Where(d => d.Name.LocalName.Equals("descr") && d.Value.Equals("delete this")).Remove();
Console.WriteLine("");
Console.WriteLine("");
Console.WriteLine("--------------------");
Console.WriteLine("AFTER");
Console.WriteLine("--------------------");
Console.WriteLine(xdoc.ToString());
Console.ReadLine();
}
}
刚刚注意到你想删除“rule”元素。 所以你可以改变这样的查询。
xdoc.Descendants().Where(d => d.Name.LocalName.Equals("rule")
&& d.Descendants().Any(dd => dd.Name.LocalName.Equals("descr") && dd.Value.Equals("delete this"))).Remove();