为什么 xpath 通配符搜索中出现“未知方法”错误

Joh*_*eil 3 xml xpath vba

我在 Excel 2003 中使用 VBA 来隔离一些 xml 节点。在返回“未知方法”错误的 xpath 通配符搜索中调用“包含”方法之前,一切都很顺利。

加载xml文件的代码是:

Public Function LoadXml()

    strPath = ThisWorkbook.Path & "\V1.xdp"
    Set docXml = New MSXML2.DOMDocument
    docXml.Load (strPath)
    Set LoadXml = docXml

End Function
Run Code Online (Sandbox Code Playgroud)

隔离节点的代码是:

Public Sub TestXpath()
    Dim docXml              As MSXML2.DOMDocument
    Dim NodeList            As IXMLDOMSelection
    Dim CurrNode            As IXMLDOMNode
    Dim n                   As Long

    'Identify xpath
    Dim strXPath As String
    strXPath = "//event/script[contains (text(),'validationScript.errorCount')]"

    'Loop through nodes and inspect attributes to ensure we've specified the correct XPath
    Set docXml = LoadXml
    Set NodeList = docXml.SelectNodes(strXPath)

    For n = 0 To (NodeList.Length - 1)
        Set CurrNode = NodeList.Item(n)
        InspectNode CurrNode
    Next

ExitSub:

    Set docXml = Nothing
    Exit Sub

End Sub
Run Code Online (Sandbox Code Playgroud)

我有一个对 MSXML v6 的参考集。知道为什么我会收到“未知方法”错误吗?

谢谢

乔恩

Joh*_*eil 5

使用 XPath 高级函数

Microsoft 在 W3C 最终确定 XPath 标准之前开发了他们的 XML 解析器,因此它基于他们自己的称为 XSL 模式的系统。(Microsoft 参与了 XPath 标准的定义,因此 XSL Pattern 是相似的,其中大部分(尽管不是全部)成为 XPath 的一部分。)为了向后兼容,Microsoft 的 XML 解析器(即使是最新的)默认使用 XSL Pattern。XSL 模式不包括诸如“包含”之类的函数,这就是发生“未知方法”错误的原因。为了解决这个问题,我们需要告诉 DOMDocument 对象 (docXml) 使用 XPath: docXml.setProperty "SelectionLanguage", "XPath"

命名空间

但是,这会产生另一个问题,因为 XPath 对名称空间更为敏感。例如,路径 //event 查找根节点的所有后代,这些后代称为“event”并且没有命名空间。因此语句 docXml.selectNodes(“//event”) 不返回任何结果,因为表单的 XML 具有默认命名空间: 。为了解决这个问题,我们需要告诉 DOMDocument 对象正在使用的命名空间并将它们映射到前缀。经过大量的网络搜索,似乎这样做的方法如下:

Const strNamespaces As String = "xmlns:xfa=' http://www.xfa.org/schema/xfa-template/2.8/ ' xmlns:xdp=' http://ns.adobe.com/xdp/ '"

docXml.setProperty "SelectionNamespaces", strNamespaces

请注意,此处定义的前缀不必与 XML 中使用的前缀相匹配,这也是因为默认命名空间没有前缀。然后我们可以在 XPath 语句中使用这些前缀。例如: docXml.selectNodes(“//xfa:event/xfa:script[contains (text(),'validationScript.errorCount')]”) docXml.selectNodes(“//xfa:event[@activity = 'initialize' ]/xfa: 脚本”)

这些现在工作。请注意,属性不继承默认命名空间,因此没有“xfa”后缀。