gpt4 book ai didi

vba - XPath 在 VBA 中返回字符串或 bool 值?

转载 作者:行者123 更新时间:2023-12-03 16:13:06 25 4
gpt4 key购买 nike

Word 宏执行 XPath 表达式的最简单方法是什么,例如:

"string(/alpha/beta)" 

"not(string(/alpha/beta)='true')"

哪个应该分别返回字符串和 bool 值? (相对于 xml 节点或节点列表)

我想避免运行 Office 2007 或 2010 的机器上不存在的 DLL。

函数 selectSingleNode(queryString As String) 返回一个 IXMLDOMNode,所以不会这样做。

换句话说,类似于 .NET 的 xpathnavigator.evaluate [1],这是做什么的?

[1] http://msdn.microsoft.com/en-us/library/2c16b7x8.aspx

最佳答案

您可以使用 XSL 转换来计算 XPath 表达式,特别是 xsl:value-of .

我写了一个 Evaluate基于此原理工作的函数。它在内存中创建一个 XSL 样式表,其中包含一个 XSL 模板,该模板将采用 XPath 表达式,对其求值,并返回一个新的 XML 文档,该文档包含在 <result> 中的结果。节点。它会检查以确保 value-of返回一些东西(如果没有则抛出错误),如果是,它将 XPath 表达式的结果转换为以下数据类型之一:Long , Double , Boolean , 或 String .

以下是我用来练习代码的一些测试。我用了 books.xml来自您链接到的 MSDN 页面的文件(如果您想运行这些测试,您必须将路径更改为 books.xml)。

Public Sub Test_Evaluate()

Dim doc As New DOMDocument
Dim value As Variant

doc.async = False
doc.Load "C:\Development\StackOverflow\XPath Evaluation\books.xml"

Debug.Assert (doc.parseError.errorCode = 0)

' Sum of book prices should be a Double and equal to 30.97
'
value = Evaluate(doc, "sum(descendant::price)")
Debug.Assert TypeName(value) = "Double"
Debug.Assert value = 30.97

' Title of second book using text() selector should be "The Confidence Man"
'
value = Evaluate(doc, "descendant::book[2]/title/text()")
Debug.Assert TypeName(value) = "String"
Debug.Assert value = "The Confidence Man"

' Title of second book using string() function should be "The Confidence Man"
'
value = Evaluate(doc, "string(/bookstore/book[2]/title)")
Debug.Assert TypeName(value) = "String"
Debug.Assert value = "The Confidence Man"

' Total number of books should be 3
'
value = Evaluate(doc, "count(descendant::book)")
Debug.Assert TypeName(value) = "Long"
Debug.Assert value = 3

' Title of first book should not be "The Great Gatsby"
'
value = Evaluate(doc, "not(string(/bookstore/book[1]/title))='The Great Gatsby'")
Debug.Assert TypeName(value) = "Boolean"
Debug.Assert value = False

' Genre of second book should be "novel"
'
value = Evaluate(doc, "string(/bookstore/book[2]/attribute::genre)='novel'")
Debug.Assert TypeName(value) = "Boolean"
Debug.Assert value = True

' Selecting a non-existent node should generate an error
'
On Error Resume Next

value = Evaluate(doc, "string(/bookstore/paperback[1])")
Debug.Assert Err.Number = vbObjectError

On Error GoTo 0

End Sub

这是 Evaluate 的代码函数( IsLong 函数是一个辅助函数,使数据类型转换代码更具可读性):

注:barrowc在评论中提到,您可以通过替换 DOMDocument 来明确您要使用的 MSXML 版本。带有特定于版本的类名,例如 DOMDocument30 (MSXML3) 或 DOMDocument60 (MSXML6)。编写的代码将默认使用 MSXML3,它目前部署得更广泛,但 MSXML6 具有更好的性能,并且作为最新版本,是 Microsoft 当前推荐的版本。

看问题 Which version of MSXML should I use?有关不同版本的 MSXML 的更多信息。
Public Function Evaluate(ByVal doc As DOMDocument, ByVal xpath As String) As Variant

Static styleDoc As DOMDocument
Dim valueOf As IXMLDOMElement
Dim resultDoc As DOMDocument
Dim result As Variant

If styleDoc Is Nothing Then

Set styleDoc = New DOMDocument

styleDoc.loadXML _
"<xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>" & _
"<xsl:template match='/'>" & _
"<result>" & _
"<xsl:value-of />" & _
"</result>" & _
"</xsl:template>" & _
"</xsl:stylesheet>"

End If

Set valueOf = styleDoc.selectSingleNode("//xsl:value-of")
valueOf.setAttribute "select", xpath

Set resultDoc = New DOMDocument
doc.transformNodeToObject styleDoc, resultDoc

If resultDoc.documentElement.childNodes.length = 0 Then
Err.Raise vbObjectError, , "Expression '" & xpath & "' returned no results."
End If

result = resultDoc.documentElement.Text

If IsLong(result) Then
result = CLng(result)
ElseIf IsNumeric(result) Then
result = CDbl(result)
ElseIf result = "true" Or result = "false" Then
result = CBool(result)
End If

Evaluate = result

End Function

Private Function IsLong(ByVal value As Variant) As Boolean

Dim temp As Long

If Not IsNumeric(value) Then
Exit Function
End If

On Error Resume Next

temp = CLng(value)

If Not Err.Number Then
IsLong = (temp = CDbl(value))
End If

End Function

关于vba - XPath 在 VBA 中返回字符串或 bool 值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4115837/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com