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

时间:2013-09-10 13:25:37

标签: xml vba xpath

我在Excel 2003中使用VBA来隔离一些xml节点。一切都很好,直到在xpath通配符搜索中调用'contains'方法,其中返回'unknown method'错误。

加载xml文件的代码是:

Public Function LoadXml()

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

End Function

隔离节点的代码是:

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

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

由于

乔恩

1 个答案:

答案 0 :(得分:3)

使用XPath更高功能

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

命名空间

但是,这会产生另一个问题,因为XPath对命名空间更敏感。例如,路径//事件查找根节点的所有后代,这些后代称为“事件”并且没有命名空间。因此,语句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:script”)

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