从xmlDoc中删除节点,如何删除父节点?
Posted
技术标签:
【中文标题】从xmlDoc中删除节点,如何删除父节点?【英文标题】:Remove node from xmlDoc, how to delete the parentNode? 【发布时间】:2012-08-10 11:15:16 【问题描述】:我有一个 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();
【问题讨论】:
在您的最后一个 XML 示例中,我假设</Set></Set></Set>
的出现实际上应该是 </Set><Set></Set>
?
当然必须有一个标签。有一次我在编辑这个问题,但在我保存问题后它就消失了。
No 是我得到的,这是正确的。第一个用于第一个 </Set></Set></Set>
永远不会正确,因为它不会产生有效的 XML。
对不起,这两个删除的节点当然必须是我认为您的问题是 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
(例如 Attribute、Document、DocumentFragment、Entity、Notation 节点),则此代码将中断。如果您认为这是一种可能的情况,您可能希望包含适当的 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,因此该解决方案应该可以让您朝着正确的方向前进。
【讨论】:
nameDict 只是一个不需要删除名称的字典。节点是我选择的节点,所以在这个例子中所有的这可以在 linq to 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")
但这里看不到任何其他解决方案。
【讨论】:
【参考方案3】:你可以这样尝试..
1) 读取标签并使用内部xml复制所有子节点。
2) 现在转到 MainParents 的根节点。
3) 现在将内部 xml 字符串替换为您在第一步中读取的 xml 字符串。
【讨论】:
以上是关于从xmlDoc中删除节点,如何删除父节点?的主要内容,如果未能解决你的问题,请参考以下文章