2011-12-22 3 views
1

노드 후보 집합을 반복하는 동안 XmlDocument에서 노드를 삭제하여 XmlDocument를 수정하려고합니다. 문제는 노드에 206 개의 요소가 있지만 MoveNext()가 요소 1 뒤에 false를 반환한다는 것입니다.XmlDocument를 XPathNodeIterator로 반복하면서 수정하는 중

데이터를 수정하기 때문에이 오류가 발생할 수 있습니까? 이 문제를 어떻게 해결할 수 있습니까? 아니면 제가 누락 된 이유가 있습니까? 내 코드는 아래와 같습니다.

동일한 작업 (XML 파일에서 노드를 선택적으로 삭제)을 수행하는 다른 방법도 올바르게 작동합니다. documentation here (에서 "주의")에서

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); 

답변

2

은 :

현재 노드 또는 조상 을 편집 할 경우 XPathNodeIterator를 사용하여, 사용자의 현재 위치가 손실됩니다. 노드 수를 편집하려면 XPathNavigator 배열을 만들고 의 모든 노드를 배열로 복사 한 다음 배열을 반복하고 노드를 수정하십시오.

+0

글쎄, 지금은 바보 같다. 나는 그 페이지를 샅샅이 뒤졌고 그 부분을 완전히 놓쳤습니다. 매력처럼 일했습니다, 고마워요. –

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(); 
     } 
관련 문제