我正在尝试通过在迭代候选节点集时从中删除节点来修改XmlDocument。我遇到的问题是,即使节点有206个元素,MoveNext()在元素1之后返回false。
这可能是因为我正在修改数据吗?我怎么能绕过这个?还是我错过了其他原因?我的代码如下。
完成相同事情的任何其他方式(有选择地从XML文件中删除节点)也可以正常工作。
XmlReader reader = XmlReader.Create(myFile.FullName);
// Load document
XmlDocument document = new XmlDocument();
document.Load(reader);
XPathNavigator navigator = document.CreateNavigator();
// Select elementD nodes with the correct format (there are other elementD nodes that we
// want to ignore
XPathNodeIterator nodes = navigator.Select("/elementA/elementB/elementC/elementB/elementD");
// Keep count of how many nodes we've deleted
int count = 0;
while (nodes.MoveNext)
{
moreNodes = nodes.MoveNext();
XPathNavigator node = nodes.Current;
logger.log(node.ToString());
string name = node.GetAttribute("name", "");
// If name isn't a valid name, delete it from the document
if (!validNames.Contains(name))
{
count++;
// Get the parent node (elementB)
XPathNavigator elementBNode = node.SelectSingleNode("..");
// And its parent node (elementC)
XPathNavigator elementCNode = elementBNode.SelectSingleNode("..");
// Delete the elementB node
elementBNode.DeleteSelf();
// It the elementC node is empty, then delete it as well
if (!elementCNode.HasChildren)
{
elementCNode.DeleteSelf();
}
}
}
// Make sure the document gets formatted nicely
XmlWriterSettings settings= new XmlWriterSettings();
settings.Indent = true;
settings.IndentChars = (" ");
// Write out the modified document
XmlWriter writer = XmlWriter.Create(myFile + ".modified", settings);
document.WriteTo(writer);
答案 0 :(得分:2)
来自documentation here(在“备注”下):
使用
XPathNodeIterator
时,如果您编辑当前节点或任何节点 它的祖先,你现在的位置丢失了。如果你想编辑一个 您选择的节点数量,创建一个XPathNavigator
数组, 然后将XPathNodeIterator
中的所有节点复制到数组中 迭代数组并修改节点。
答案 1 :(得分:0)
这是克隆要删除的元素的代码示例。
XPathNodeIterator iteratorRef = nav.Select(path, namespaceManager);
List<XPathNavigator> toDelete = new List<XPathNavigator>();
while (iteratorRef.MoveNext())
{
bool condition = IsElementToDelete(iteratorRef);
if (condition)
{
// It is important to clone Current otherwise you'll sameelement in toDelete
toDelete.Add(iteratorRef.Current.Clone());
}
}
foreach (XPathNavigator xPathNavigator in toDelete)
{
xPathNavigator.DeleteSelf();
}