【问题标题】:Remove a node from XML file in MS Project VBA [closed]从 MS Project VBA 中的 XML 文件中删除节点 [关闭]
【发布时间】:2011-07-27 06:23:23
【问题描述】:

我想使用 MS Project 2007 中的 VBA 从我的 xml 文件中删除一个节点。

应该很简单,但我无法让它运行。

这是我的 XML

<config id="config" ConfigSaveDate="2011-03-31 21:32:55" ConfigSchemaVersion="1.02">
    <Custom> 
    </Custom>
    <Program>
      <DateFormat>yyyy-mm-dd hh:mm:ss</DateFormat> 
    </Program>
    <ProjectFile ProjectFileName="projectfile1.mpp">
      <RevisionNumber>201</RevisionNumber> 
      <FileName>projectfile1.mpp</FileName> 
      <LastSaveDate>2011-03-23 16:45:19</LastSaveDate> 
    </ProjectFile>
    <ProjectFile ProjectFileName="projectfile2bedeleted.mpp">
      <RevisionNumber>115</RevisionNumber> 
      <FileName>projectfile2bedeleted.mpp</FileName> 
      <LastSaveDate>2011-03-31 21:12:55</LastSaveDate> 
    </ProjectFile>
    <ProjectFile ProjectFileName="projectfile2.mpp">
      <RevisionNumber>315</RevisionNumber> 
      <FileName>projectfile2.mpp</FileName> 
      <LastSaveDate>2011-03-31 21:32:55</LastSaveDate> 
    </ProjectFile>
</config>

这是我的 VBA 代码

Function configProjListDelete(configPath As String, ProjFiles As Variant) As Integer

  ' This function shall delete <ProjectFile> tags from the config.xml
  ' and shall delete coresponding project xml files from HD
  ' It shall return number of deleted files

  ' configPath is the  path to the xml folder
  ' ProjFiles is an array of file names of to be deleted files in above mentioned folder

  Dim xml As MSXML2.DOMDocument
  Dim RootElem As MSXML2.IXMLDOMElement
  'Dim cxp1 As CustomXMLPart
  Dim delNode As MSXML2.IXMLDOMNode ' XmlNode 'MSXML2.IXMLDOMElement
  Dim fSuccess As Boolean
  Dim ProjectFileList As MSXML2.IXMLDOMElement
  Dim fn As Variant 'file name in loop
  Dim i As Integer
  Dim delCnt As Integer

  If Not FileExists(configPath) Then
    ' given configFile doesn't exist return nothing
    Debug.Print "  iven config file doesn't exist. File: " & configPath
    GoTo ExitconfigProjListDelete
  End If

  'TODO: Catch empty ProjectFiles

  ' Initialize variables
  Set xml = New MSXML2.DOMDocument

  On Error GoTo HandleErr
  ' Load the  XML from disk, without validating it.
  ' Wait for the load to finish before proceeding.
  xml.async = False
  xml.validateOnParse = False
  fSuccess = xml.Load(configPath)
  On Error GoTo 0
  ' If anything went wrong, quit now.
  If Not fSuccess Then
    GoTo ExitconfigProjListDelete
  End If

  Set RootElem = xml.DocumentElement

  Debug.Print "- " & xml.getElementsByTagName("ProjectFile").Length & " ProjectFiles in config."

  i = 0
  delCnt = 0
  ' Loop through all ProjectFiles
  For Each ProjectFileList In xml.getElementsByTagName("ProjectFile")

    ' check if each project file name is one of the files to be deleted
    For Each fn In ProjFiles
      If fn = ProjectFileList.getElementsByTagName("FileName").NextNode.nodeTypedValue Then
        Debug.Print fn & " shall be deleted"

        ' remove it from the document

        ' here I'm struggeling!
        '#################################################
        ' How to delete the node <ProjectFile> and its childNodes?
        Set delNode = ProjectFileList.ParentNode
        xml.DocumentElement.RemoveChild (ProjectFileList) ' Error: 438 rough translation: "Object doesn't support this methode"

        ' This is all I've tried, but nothing works
        '===========================================
        'RootElem.RemoveChild (delNode)
        'xml.RemoveChild (delNode)
        'RootElem.RemoveChild (ProjectFileList.SelectSingleNode("ProjectFile"))
        'ProjectFileList.ParentNode.RemoveChild (ProjectFileList.ChildNodes(0))

        'Set objParent = datenode.ParentNode
        'xmldoc.DocumentElement.RemoveChild (objParent)

        'Set ProjectFileList = Empty


        delCnt = delCnt + 1
      End If
    Next fn

    i = i + 1
  Next ProjectFileList

  ' Save XML File
  If checkAppPath("Trying to update config file.") Then
    xml.Save CustomProperty("XMTMLMonitoring_AppPath") & "\" & m2w_config("SubFolder") & "\" & m2w_config("SubFolderData") & "\" & m2w_config("XMLConfigFileName")
    Debug.Print "  - Config has been updated and saved."
  Else
    MsgBox "Config data not exported to web." & Chr(10) & "Folder: '" & CustomProperty("XMTMLMonitoring_AppPath") & "\" & m2w_config("SubFolder") & "\" & m2w_config("SubFolderData") & Chr(10) & "doesn't exist. ", vbOKOnly, HEADLINE
  End If

  Set xml = Nothing

  configProjListDelete = delCnt

ExitconfigProjListDelete:
Exit Function

HandleErr:
  Debug.Print "XML File reading error " & Err.Number & ": " & Err.DESCRIPTION
  MsgBox "Error " & Err.Number & ": " & Err.DESCRIPTION
  On Error GoTo 0


End Function

我很高兴得到一些帮助!

【问题讨论】:

  • 仅供参考,如果您可以将代码的相关部分提供给我们并对其进行格式化,这样我们就不必向下和向右滚动 4 个屏幕来查看整个内容!

标签: xml vba ms-project


【解决方案1】:

你知道XPath吗?从代码的痛苦外观来看,您没有。与其使用大量野蛮的 DOM 方法组合来访问所需的节点,不如省去很多麻烦,只需使用 XPath 在一行中访问它。

如果我正确理解您要执行的操作,那么类似以下内容可以替换您的整个双循环,从 i=0Next ProjectFileList

For i = LBound(ProjFiles) To UBound(ProjFiles)
    Set deleteMe = XML.selectSingleNode( _
        "/config/ProjectFile[@ProjectFileName='" & ProjFiles(i) & "']")
    Set oldChild = deleteMe.parentNode.removeChild(deleteMe)
Next i

“引号”中的内容是 XPath。希望这会有所帮助。

附带说明一下,在您的 XML 文件中使用包含完全相同信息的 ProjectFileName 属性和 FileName 元素似乎效率低下、令人困惑且容易出错。这是怎么回事?

【讨论】:

  • +1 但是请注意,问题中的原始代码(可能是无意的)使用较旧的 MSXML v3.0,它不使用 XPath 作为其默认查询语言 - 它使用 XSLPatterns 代替。指定DOMDocument 与指定DOMDocument30 相同。建议将其更改为 DOMDocument60 以使用 MSXML,v6.0 将是有益的,因为 XPath 将成为默认查询语言。或者,您可以设置 MSXML,v3.0 以使用 XPath - 请参阅 blogs.msdn.com/b/xmlteam/archive/2006/10/23/…
  • 好点!这引起了我的注意。
  • 你好,Jean,效果很好!我将整理我的代码并查看 XML 模式。痛苦是正确的词!这很糟糕。所以你不仅帮我解决了我的问题——你把我推到了前面!非常感谢!
猜你喜欢
  • 2014-09-13
  • 2013-02-19
  • 2023-03-24
  • 2018-03-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-23
  • 1970-01-01
相关资源
最近更新 更多