从xmlDoc中删除节点,如何删除父节点?
问题描述:
我有一个xmlDoc中,这是它的一个部分:从xmlDoc中删除节点,如何删除父节点?
<Main>
<Set>
<MId>1</MId>
<RName>
<MetaData>
<PrdctName>
Test 1
</PrdctName>
</MetaData>
</RName>
</Set>
<Set>
<MId>1</MId>
<RName>
<MetaData>
<PrdctName>
Test 2
</PrdctName>
</MetaData>
</RName>
</Set>
<Set>
<MId>1</MId>
<RName>
<MetaData>
<PrdctName>
Test 3
</PrdctName>
</MetaData>
</RName>
</Set>
<Set>
<MId>2</MId>
<RName>
<MetaData>
<PrdctName>
Test 1
</PrdctName>
</MetaData>
</RName>
</Set>
</Main>
通过选择prdctName其余必须从xmlDoc中除去。例如,如果我选择“测试1” 结果必须是:
<Main>
<Set>
<MId>1</MId>
<RName>
<MetaData>
<PrdctName>
Test 1
</PrdctName>
</MetaData>
</RName>
</Set>
<Set>
<MId>2</MId>
<RName>
<MetaData>
<PrdctName>
Test 1
</PrdctName>
</MetaData>
</RName>
</Set>
</Main>
的问题是,我不知道如何删除标记。 所以一个删除后的XML看起来像现在这样:
<Main>
<Set>
<MId>1</MId>
<RName>
<MetaData>
<PrdctName>
Test 1
</PrdctName>
</MetaData>
</RName>
</Set>
<Set/>
<Set/>
<Set>
<MId>2</MId>
<RName>
<MetaData>
<PrdctName>
Test 1
</PrdctName>
</MetaData>
</RName>
</Set>
</Main>
哪个代码我必须写删除标签也?
这是我现在使用的代码的一部分:
foreach (XmlNode chkNode in nodes)
{
string currentName = "Test 1";
if (!nameDict.ContainsKey(currentName))
chkNode.ParentNode.RemoveAll();
}
答
我认为你的问题是XmlNode.RemoveAll()
只能删除节点的子节点,而chkNode.ParentNode
属性选择的节点是<Set>
标签。所以当你删除所有的孩子,你剩下一个空的<Set/>
节点。您还需要能够移除该特定节点。
适应现有的方法中,你需要做的是这样的:
foreach (XmlNode chkNode in nodes)
{
string currentName = "Test 1";
if (!nameDict.ContainsKey(currentName))
{
XmlNode parent = chkNode.ParentNode;
parent.ParentNode.RemoveChild(parent);
}
}
当然,我不能对此进行测试的,是因为我不知道究竟是什么nameDict
和nodes
是。
为了完整起见,这个代码将打破如果chkNode
或chkNode.ParentNode
是XmlNodes
不能具有父母(如实体,文档的DocumentFragment,实体,符号节点)。如果你认为这是一个可能的方案,您可能要包括适当的null检查或在try-catch
喜欢的东西包装这个方法:
XmlNode parent = chkNode.ParentNode;
if (parent != null && parent.ParentNode != null)
parent.ParentNode.RemoveChild(parent);
或者:
try
{
XmlNode parent = chkNode.ParentNode;
parent.ParentNode.RemoveChild(parent);
}
catch (NullReferenceException ex)
{
// do something with exception
}
有LINQ的几个选择以更好的方式完成你想要的东西,但是由于你使用的是C#2.0,所以这个解决方案应该让你朝着正确的方向发展。
答
这可能与LINQ的帮助,XML和XPath来完成。查找下面的例子:
var xdocument = XDocument.Parse(xml)
xdocument.Document.Root.Elements()
.Where(element
=> !element.XPathSelectElement("RName/MetaData/PrdctName").Value.Contains("Test 1"))
.Remove();
// saving results...
xdocument.Save("somewhere.xml");
PS
不是那么好检查包含Value.Contains("Test 1")
但在这里看不到任何其他的解决方案吧。
在你最后一个XML例子,我假设的''的次数实际上应该是' '? –
psubsee2003
2012-08-10 11:17:35
当然必须有一个标签。当我编辑这个问题的时候,但是在我保存了这个问题之后它就消失了。 – Remco 2012-08-10 11:17:54
否是我得到的,这是正确的。第一个是第一个标记,另外两个来自已删除的节点。 –
Remco
2012-08-10 11:20:08