您可使用XSL转变来评价XPath的表述,特别是xsl: Value-of。
我写了<代码>Evaluate功能,该功能与这一原则有关。 它创造了一种XSL风格的记忆,其中包含一个XSL模板,该模板将采用XPath的表述方式,评价它,并退回一份新的XML文件,其中载有<代码><result> node的结果。 它对确保<条码>价值-of退回了部分内容(如果没有,就留下了一个错误)进行核对,如果是,将XPath的表述结果转换为以下几种数据之一:<条码>:Long、<条码>Double<>>>>>>>、<条码>>Boolean>、或<条码>。
这里是我用来实施该守则的一些测试。 I used the books.xml
如你想要进行这些测试,则从MSDN网页上存档(如果你想进行这些测试,那么你必须改变通往books.xml
的道路)。
Public Sub Test_Evaluate()
Dim doc As New DOMDocument
Dim value As Variant
doc.async = False
doc.Load "C:DevelopmentStackOverflowXPath Evaluationooks.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
功能,是使数据类型转换代码变得更可读的辅助功能):
<Note:As barrowc 在评论中,你可以明确你想要用哪一种版本的MSXML,将/code>替换成具体版本的类别名称,例如。 DOMDocument30
(MSXML3) or DOMDocument60
(MSXML6). 书面守则将不使用MSXML3,目前这一系统被更广泛地利用,但MSXML6的性能较好,也是最新版本,是目前推荐的Microsoft。
参看问题 我应使用何种版本的MSXML? 关于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