简单数据评估语言概述

WDTF 包含一种简单的查询语言,用于简化基于属性或关系收集目标的任务。 简单数据评估语言(SDEL)类似于 XPath。 有关 XPath 的详细信息,请参阅 XPath 参考

本主题中的以下部分介绍如何使用 SDEL。

注意

有关所有命名空间令牌及其中的属性令牌的完整列表,请参阅 SDEL 中的设备关系令牌和 SDEL 中的属性令牌。

SDEL 语法基础知识

SDEL 使用属性令牌执行匹配并检索数据。 所有 SDEL 标记只能包含字母数字字符和连字符(-)。

属性是指附加到目标的数据片段。 属性中的实际值存储为 VARIANT。 如果将比较运算符放在属性后跟 测试 值,SDEL 将执行比较匹配。 应将测试值置于单引号或双引号中--此表示法使你可以在测试值中使用实际的单引号或双引号,但不能同时使用两者。 如果测试值仅包含字母数字字符和连字符(-),则可以省略引号。

比较操作

SDEL 允许各种比较运算符遵循属性标记。 比较时,通过 VariantChangeType 方法(Microsoft Windows SDK 文档中所述)将运算符左侧的属性中的实际值设置为运算符右侧的测试值的类型。 下表显示了 SDEL 支持的不同比较运算符。

比较运算符含义相等 (=)

更改类型后,使用 VarCmp 方法(Windows SDK 文档中介绍)对其进行比较。

不平等 (!=)

小于号 (<)

小于或等于 (<=)

大于号 (>)

大于或等于 (>=)

按位“与”(&)

在对实际值和测试值执行按位 AND 之前,此运算符强制类型VT_I8。

未指定任何比较操作(且未指定任何值)

如果属性中的实际值的类型为 VT_BOOL,则根据该值满足匹配项,即不需要比较运算符执行“IsDisableable=True”。 否则,如果有任何值(除VT_EMPTY外),则满足匹配项。

当属性中有多个实际值(或数组),所有比较运算符都应解释为匹配至少一个,但不相等运算符除外,该运算符具有相反的行为。 如果根本无法比较类型(即 VariantChangeType 失败),则没有匹配项(除了不相等运算符(具有相反行为)。

了解属性命名空间

SDEL 使用命名空间令牌对属性进行分组。 有关所有命名空间令牌及其中的属性令牌的完整列表,请参阅 SDEL 中的属性令牌。

若要使用根命名空间外部的任何属性,必须为该属性加上命名空间名称,然后添加两个冒号(::))。 以下 VBScript 代码示例显示 Disk::IsRemovable 属性的值。

WScript.Echo "Is Removable?: " & DeviceObj.GetValue("Disk::IsRemovable")

使用 GetValue 和 Eval 检查目标

IWDTFTarget2::GetValue 方法允许询问目标的属性。 以下 VBScript 代码示例打印目标的 FriendlyName 属性的值

WScript.Echo "FriendlyName: " & Device.GetValue("FriendlyName")

有关属性令牌的完整列表,请参阅 SDEL 中的属性令牌。

还可以使用 IWDTFTarget2::Eval 方法针对目标评估 SDEL 语句。 Eval 返回VARIANT_TRUEVARIANT_FAL标准版。 以下 VBScript 代码示例使用 Eval 来确定是否可以禁用设备。

If Device.Eval("IsDisableable=true") Then
    WScript.Echo "Target is disableable!"
End If

还可以使用 Eval 测试属性是否存在。 传递 Eval 时,如果属性或命名空间包含任何值(而不是 VT_EMPTY),则 Eval 将返回VARIANT_TRUE。 以下 VBScript 代码示例使用 Eval 来确定目标是否具有符号链接关键字 (keyword)。

If Device.Eval("SymbolicLink") Then
    WScript.Echo "Target has a SymbolicLink!"
End If

此外,缺少比较运算符但包含 VT_BOOL 值的属性对其应用了隐式“=true”比较。 此隐式比较意味着“IsDisableable”等效于“IsDisable='true'”。

测试通常涉及检查相关设备更改状态时会发生什么情况。 例如,当 U 盘被禁用时,附加到它的设备是否能够正确处理状态更改? 此外,你可能希望根据相关设备中的信息查找设备。 为了支持此功能,SDEL 包括一种在任一属性或命名空间之前指定一个或多个逻辑关系(但不是在任一属性或命名空间之后)的方法。 关系标记由正斜杠(/)与属性或命名空间分隔。 以下 VBScript 代码示例打印目标父设备的 FriendlyName 属性的值

WScript.Echo "FriendlyName: " & Device.GetValue("parent/FriendlyName")

还可以合并关系修饰符。 以下 VBScript 代码示例打印目标对象的祖父设备的 FriendlyName 属性的值

WScript.Echo "FriendlyName: " & Device.GetValue("parent/parent/FriendlyName")

有时,设备具有多对多关系。 例如,逻辑存储卷可能驻留在许多物理磁盘上,而这些单个磁盘可能会为许多卷提供空间。

在 WDTF 中,所有非虚拟设备(即物理存在的设备)都是根设备的后代(可从 RootDevice 属性中检索)。 (有关虚拟设备的详细信息,请参阅 创建 WDTF 方案。)

使用 GetRelations 收集目标

下图显示了 IWDTFTarget2::GetRelations 方法。

说明 WDTF 中 Target::GetRelations 方法的示意图,其中显示了单个目标和相关目标。

IWDTFTarget2::GetRelations 方法仅接受 SDEL 语句语法的关系说明符部分,并返回一个 IWDTFTargets2 集合接口,该接口包含满足关系条件的所有目标。 以下 VBScript 代码示例返回一个集合,该集合包含原始目标及其所有同级。

Set TestDevices = Device.GetRelations("parent/child/", "")

GetRelations 的第二个参数可以选择包含要传递给满足特定关系的每个目标的 Eval 方法的语句。 例如,如果将 IsDisableable=true 添加为第二个参数,前面的代码示例将仅返回可禁用的设备及其同级。

如果没有匹配项,则返回包含零项的集合。

使用查询收集目标

IWDTFDeviceDepot2 接口包含查询方法。 此方法采用专为 IWDTFTarget2::Eval 方法设计的 SDEL 语句,并返回 IWDTFTargets2 集合接口的新实例,该接口包含满足查询条件的目标子集。 以下 VBScript 代码示例枚举所有非虚拟设备,并显示每个设备的友好名称。

For Each Device In WDTF.DeviceDepot.Query("IsPhantom=false")
    WScript.Echo Device.GetValue("FriendlyName")
Next

返回的集合具有 IWDTFTargets2::Query 方法,该方法与 IWDTFDeviceDepot2::Query 具有相同的实现 IWDTFTargets2::Query 从满足 SDEL 语句的原始集合中返回一部分目标。

SDEL 中的布尔逻辑

IWDTFTarget2::GetRelations 方法只能接受布尔 OR 运算符,但对 IWDTFTargets2::QueryIWDTFTarget2::Eval IWDTFTarget2::GetValue 方法的调用可以使用布尔 OR 运算符。 对于 Query 方法和 Eval 方法,运算符将像普通布尔运算符一样,按预期返回结果。 但是,对于 GetValue 方法, AND 将组合自身两侧的值, OR 将仅返回找到的第一个值(从左侧开始)。

SDEL 中的括号

所有 SDEL 语句都可以使用括号来指定布尔逻辑的计算序列。 还可以使用括号在关系或命名空间下的语句中对子元素进行分组。

以下 VBScript 代码示例检索祖父设备的所有卷和子级。

Set Devices = Device.GetRelations("parent/parent/(child/ OR volume/)", "")

以下 VBScript 代码示例检索具有可移动媒体且大于 1,000,000 字节的子级的所有设备。

Set Devices = WDTF.DeviceDepot.Query("child/disk::(IsRemovable=true AND Size>1000000)")

SDEL 语法分析

如果将语法错误的 SDEL 语句传递给 WDTF 中的任何方法,该方法将失败,并返回详细的错误信息并解释问题。

注意

拼写错误的属性、命名空间或关系标记不会导致语法错误,因为 SDEL 设计为基于目标动态:SDEL 语句必须能够查询动态字段集中是否存在属性。