删除双 XML 节点

Removing double XML nodes

这里是一个 XML 文件的例子,它由根元素、父节点和子节点组成。我一直在寻找删除双节点的最佳方法(必要时),并且我尝试了很多技巧和方法来做到这一点:比如 childNode.ParentNode.RemoveChild(childNode) 等,但是我尝试的每种方法都无法正常工作(或我做错了什么,或者可能是因为 DTD;我不确定)。好吧,我找到了另一种方法,我想:与其他人分享可能会很有趣。

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE root[
  <!ELEMENT root (parent, child)>
  <!ELEMENT parent (child)>
  <!ELEMENT child EMPTY>
]>
<root>
  <parent>
    <child />
  </parent>
  <parent>
    <child />
  </parent>
  <parent>
    <child />
  </parent>
</root>

我使用Do-Loop而不是For-Next,因为我在使用For-Next循环时出错:例如child 个节点连同 parent 个节点属性(您在此示例中看不到)一起被删除,但 parent 个节点仍然存在。但是使用 Do-Loop 我得到了预期的结果(如果你想删除第一个节点以外的所有 parent 节点,那么写 Loop Until i = 0 而不是 Loop Until i = 1 . 在我的示例中,我需要前两个 parent 个节点):

Dim i As Integer = MyXmlDocument.GetElementsByTagName("parent").Count - 1
   Do
      MyXmlDocument.DocumentElement.RemoveChild(MyXmlDocument.GetElementsByTagName("parent")(i))
      i -= 1
   Loop Until i = 1
MyXmlDocument.Save(MyXmlFile)

整个代码如下(我在模块外声明了'XmlReader'、'XmlSettings'和'XmlDocument',以便能够在模块外使用它们。并且LoadSettings()Form.Load 事件调用。还有一件事必须发生:当加载 XmlDocument 时发生错误异常时,XmlReader 保持打开状态。也许通过添加 Finally : MyXmlReader.Close(),这个"issue"就解决了

Public Module Common

   Public MyXmlFile As String = My.Application.Info.DirectoryPath & "\Common\myxmlfile.xml"
   Public MyXmlReader As Xml.XmlReader
   Public MyXmlReaderSettings As New Xml.XmlReaderSettings
   Public MyXmlDocument As New Xml.XmlDocument

   Public Sub LoadSettings()
      MyXmlReaderSettings.DtdProcessing = DtdProcessing.Parse

      If File.Exists(MyXmlFile) Then
         Try
            MyXmlReader = Xml.XmlReader.Create(MyXmlFile, MyXmlReaderSettings)
            MyXmlDocument.Load(MyXmlReader)
            MyXmlReader.Close()


            If MyXmlDocument.GetElementsByTagName("parent").Count > 2 Then 
               Dim i As Integer = MyXmlDocument.GetElementsByTagName("parent").Count - 1
               Do
                  MyXmlDocument.DocumentElement.RemoveChild(MyXmlDocument.GetElementsByTagName("parent")(i))
                  i -= 1
               Loop Until i = 1
               MyXmlDocument.Save(MyXmlFile)
            End If
         Catch ex As Exception
            MsgBox(ex.ToString)   
         End Try
      End If
   End Sub
End Module

您的问题不是很清楚,但您似乎只想删除除前两个节点之外的所有 parent 个节点?

那么简单的怎么样:

Dim xml = XDocument.Load(pathToLoad)

For Each parent in xml.<root>.<parent>.Skip(2).ToList()
    parent.Remove()
Next 

xml.Save(pathToSave)