XPath 入门指南

MobileTogether 使用 XPath 作为其公式和表达式语言。

如果您知道如何在 Excel 电子表格中编写公式,那么您就可以轻松学习如何在 MobileTogether 中编写 XPath 公式或表达式。您只需要理解几个基本概念即可。MobileTogether 中的 XPath 构建器可以帮助您轻松构建 XPath 表达式,就像 Excel 中的公式构建器可以帮助您在电子表格中编写公式一样。

那么,为什么它被称为 XPath 呢?

“X” 在 XPath 中代表其起源于 XML(可扩展标记语言),而 “Path” 则源于您使用类似于路径的格式来识别数据中的各个部分。在 MobileTogether 中,您访问的任何数据源都会在 MobileTogether 设计器窗口右侧的“页面来源”部分以一种小型树状结构来表示。每个树状结构都以一个根节点开始,该根节点具有名称,例如 $XML1 或 $DB1,然后在该根节点下方是各个数据部分,这些数据部分被称为“元素”。这些元素以逻辑方式嵌套,因此最好将它们表示为树形结构,您可以折叠和展开每个元素,以查看其下方的内容。MobileTogether 的一个优点是:无论底层数据来自数据库、XML 文档、Web 服务或任何其他数据源,它们都以相同的方式呈现,并且可以以相同的方式访问。

XPath 允许您在这些树状结构中进行导航,从而将您的数据元素与移动设备屏幕上的用户界面对象关联起来。这与您在计算机硬盘上浏览文件系统中的目录树的方式非常相似。无论您习惯使用 Windows、Linux 还是 MacOS,硬盘上的文件始终可以通过路径来访问,例如:

C:\Users\Spock\Documents\ScienceRecords 	(Windows)
/Users/Kirk/Documents/BeautifulAlienWomen	(Linux/Mac)

那么,让我们通过一个例子来比较一下 XPath 表达式:

$DB1/salesdata/region/month/gadgets

正如您所看到的,其核心思想完全相同。您使用XPath来遍历数据树结构,就像您使用路径表达式来浏览计算机硬盘上的文件系统一样。XPath使用"/"(正斜杠)字符来分隔路径中的各个元素,这与Linux和macOS系统中用该字符分隔目录的方式相同。

有趣的是,这种类比于目录路径的概念也适用于 XPath 中两种非常常见的缩写。 就像在文件系统中,单个点 "." 指的是当前目录,在 XPath 中,"." 也指当前元素。 同样,双点 ".." 在文件系统中指的是父目录,在 XPath 中也指父元素。

属性。

如果您的数据来源是 XML 文档,或者是由 Web 服务返回的 XML 数据,那么其中包含的数据主要有两种形式:元素和属性。元素是 XML 中的核心数据项,可以嵌套,因此一个元素可以在树形结构中包含子元素。而属性则是附加到元素上的简单数据值。在“页面资源”下的树形结构中,您会看到属性前面带有“=”(等号)。这是因为在 XML 文档中,属性通常以“属性名=值”的形式出现,例如:color="green"。

当您需要在 XPath 表达式中引用属性时,需要在属性名称前加上一个 "@" 符号:

$XML1/salesdata/region/@name

除此之外,您也可以对元素和属性执行相同的操作,例如,您可以在计算中使用它们,或者将它们的值绘制在图表上,并且您可以在 MobileTogether 设计中的用户界面对象中为它们分配值。

谓词。

有时,仅仅指定数据中某个元素的路径还不够。您真正想要做的是,根据一定的条件选择一部分数据,例如,为了将这些数据显示在图表上,或者以表格的形式呈现给用户。

如果您曾经使用过关系型数据库,那么这就像 SQL 语句中的常见的 WHERE 子句。它允许您从数据库中筛选出符合特定条件的数据。

XPath 中与之对应的概念被称为“谓词”(Predicates)。XPath 谓词允许您指定选择标准,从而只选择符合指定标准的特定元素。谓词以逻辑表达式的形式,并用方括号 [] 括起来,例如:

$XML1/salesdata/region[@name=”East”]/Month

这句话的解读方式是:在名为“XML1”的数据源中,首先找到名为“salesdata”的元素,然后进入其子元素“region”,选择所有“attribute name”属性值为“East”的区域,最后选择这些区域各自对应的子元素“Month”。

操作员。

正如我们一开始所说,XPath 是一种完整的表达式语言。这意味着它不仅可以帮助您选择特定的数据,还可以让您对这些数据进行各种常见的数学运算,从而计算出新的值。就像 Excel 中的公式可以根据您现有的数据计算出新的值一样,您也可以使用 MobileTogether 中的 XPath 表达式来实现同样的功能。

假设您想创建一个移动端发票解决方案,并且希望在您的移动端表单中显示某一项的合计金额:

$DB1/sales/invoice/item/quantity * $DB1/sales/invoice/item/price

假设您的数据结构中,数量和价格是分开存储的(并且用户可以修改价格),那么您就可以简单地使用乘法运算(使用“*”符号)来计算该行项目的总金额。

XPath 的一个非常实用的功能是,您可以通过在路径中直接使用括号进行乘法运算,从而减少大量的输入。当您到达路径中的合适位置时,就可以使用这种简写形式,它与上述表达式具有相同的含义:

$DB1/sales/invoice/item/(quantity * price)

同样,您可以使用 + (加号) 和 - (减号) 作为数学运算符。但是,您需要使用不同的符号来进行除法运算。由于我们已经使用 / (斜杠) 来分隔路径中的各个元素,因此我们不能使用相同的字符来表示除法。因此,在 XPath 中,除法运算符是 "div",用于执行实数除法,而 "idiv" 用于执行整数除法(即,如果您希望结果是整数而不是实数)。

此外,一个良好的习惯——有时甚至是必要的——是在操作符周围添加空格,以确保它们不会被误认为是元素或属性名称的一部分。这一点尤其适用于“-”(减号)操作符。

序列。

XPath 和目录路径之间的一个重要区别在于,虽然目录路径通常只标识一个特定的文件或目录,但 XPath 表达式实际上可以引用多个数据节点(即,一个元素或一个属性)。事实上,每个 XPath 表达式的结果总是返回一个节点序列。

这最好理解为,大多数数据库包含一系列结构相似的数据行,就像大多数XML文档的核心也包含一系列名称相同且结构相似的元素。XPath的创建是为了让开发者能够轻松地处理这类数据集。因此,能够一次性访问整个节点集合具有巨大的优势,正如我们将在接下来的几章中看到的。

同时,有时可能需要明确地在 XPath 表达式中定义序列,这时您可以通过列举值的方式来实现,格式如下:

(1, 2, 3, 4, 5)

序列是有序的,因此上述序列与序列 (3, 5, 2, 4, 1) 截然不同。序列可以包含您数据中的节点,也可以包含常量数值或常量字符串。

例如,一个可能的字符串序列可能如下所示:

("a", "b", "c", "d", "e")

最后,但同样重要的一点是,您可以使用范围运算符来指定一系列有序的数值:

(1 to 5)

这等同于序列 (1, 2, 3, 4, 5)。正如您所看到的,这个范围运算符可以用于快速构建数值序列,而手动列举这些序列在数字变大时会变得非常繁琐。

用于表达。

如果您之前使用过任何其他编程语言,您会发现“for”循环是一种非常常见的工具,它以某种形式存在于大多数现代编程语言中。同时,它也是 XPath 表达式语言中不可或缺的一部分。

在 XPath 中,`for` 表达式最简单的形式允许您使用一个临时循环变量来遍历一系列值或节点,该变量直接在 `for` 表达式中定义。例如,以下表达式:

for $i in (1 to 10) return 2 * $i

该程序将通过遍历原始序列(从1到10),并使用变量 $i,然后对序列中的每个数据点计算 2 * $i,从而生成数字序列 (2, 4, 6, 8, 10, 12, 14, 16, 18, 20)。

既然我们知道任何 XPath 表达式都可以返回一个节点序列,那么我们也可以利用 `for` 表达式来遍历这些节点,并进行一些数学运算。例如,要遍历发票上的所有条目,并计算每个条目的金额,我们可以使用以下表达式:

for $x in $DB1/sales/invoice/item return $x/price * $x/quantity

在这种情况下,`x` 将是我们循环的变量,它会遍历每个条目元素,而这个表达式将返回一个序列,其中包含我们发票中每一行的金额。 假设我们的发票原始数据中包含以下两个条目元素:

<item>
  <quantity>5</quantity>
  <price>12.50</price>
</item>
<item>
  <quantity>3</quantity>
  <price>27.85</price>
</item>

然后,之前的 XPath 表达式将返回序列 (62.5, 83.55),这两个数值分别代表发票上每一项明细的金额。

功能。

XPath 中的函数与其他编程语言(如 Excel 公式)中的函数一样,您可以通过调用函数名并在括号中传递一组函数参数来使用它们。例如,要计算序列 (3, 9, 14) 的总和,您将这样写:

sum( (3, 9, 14) )

这样,我们得到的结果是26。请注意,在这种情况下,外层的括号是`sum()`函数的调用的一部分,而内层的括号是作为单个参数传递给该函数的序列。

同样地,我们可以通过将所有明细项目加总来计算出之前示例中的发票总额:

sum( for $x in $DB1/sales/invoice/item
    return $x/price * $x/quantity )

这可以非常有用,例如,在移动解决方案中构建交互式表单时,您可以显示数据的总计,并且这些总计会随着用户在表单中输入数据而动态变化。

XPath 包含大量的内置函数,用于处理数值(例如:round、abs、floor 等)、字符串操作(例如:concat、转换为小写、contains、replace)、时间间隔、日期和时间,以及对序列的聚合操作(例如:count、sum、avg、min、max)。MobileTogether 中的 XPath 构建器使得使用这些函数编写 XPath 表达式变得非常容易,因为它提供了一个方便的目录,其中包含了所有可用函数的简要描述以及所需参数的信息。这些函数按照逻辑分组显示,因此您可以轻松找到适合您特定需求的函数。

如果表达式。

在编程语言中,以及在表达式语言中,经常需要根据特定条件是否满足来选择不同的计算方式。这时,`if`语句就派上用场了。`if`语句允许您根据您指定的测试条件,定义不同的结果。

在 XPath 中,if 语句的格式如下:

if ( test-expression ) then expression else expression

其中,"test-expression" 是一个逻辑 XPath 表达式,它会返回真 (true) 或假 (false)。

例如,我们可以在 MobileTogether 中使用这样的语句,使标签或编辑框的文本颜色根据数据中包含的数值而变化。假设我们从数据源中选择了一个元素,并将其与一个编辑框关联。我们可以选择该编辑框,然后进入“属性”选项卡,在那里我们可以选择“文本颜色”属性。与其使用颜色选择器来定义颜色,我们可以点击工具栏中的 XPath 图标,并选择通过 XPath 表达式来定义该输入框的文本颜色:

if ( $MT_ControlValue >= 0 ) then "green" else "red"

在这里,我们使用 MobileTogether 内置的一个变量来引用当前控件,并且我们正在测试该值是否大于或等于零。

根据测试结果,显示结果将呈现“绿色”或“红色”,并且我们的文本颜色会根据用户的输入动态变化。

同样,还有许多内置变量,它们都以“$MT_”开头,允许您根据设备的屏幕尺寸、操作系统、语言以及其他诸多因素做出决策。 所有这些内置全局变量都可以在 MobileTogether Designer 的“项目”菜单中的“全局变量”对话框中查看。

XQuery

到目前为止,我们主要讨论的是XPath,这主要是出于历史原因,因为它是更广为人知的基于XML的表达式语言,并且已经存在了15年。然而,除了XPath之外,MobileTogether还支持更强大的XQuery语言。XQuery是XPath的真正超集,这意味着每一个有效的XPath表达式也是一个有效的XQuery表达式。然而,XQuery增加了一些额外的强大功能,这些功能允许您完成更多操作,并且让您能够实时地操作或构建整个XML文档。

FLWOR 表达式。

最重要的 XQuery 表达式是所谓的 FLWOR 表达式。FLWOR 是一个首字母缩写词,代表“For-Let-Where-Order-Return”,通常发音为“flower”。它在功能上等同于 SQL 中的 SELECT 语句,具有类似的子句,例如 FROM、WHERE、ORDER BY 等。FLWOR 表达式使我们能够比单纯的 XPath 表达式更高效、更强大地查询 XML 和数据库数据,并且它是 XQuery 的核心。

在之前的 XPath 讨论中,我们已经接触过表达式中的 "for" 部分,因此 FLWOR 表达式的这部分对您来说应该不陌生。同样,我们之前也见过 "for" 表达式中的 "return" 子句。然而,XQuery 极大地扩展了 "return" 子句的灵活性,它允许您使用构造器从头开始创建完整的 XML 树。本质上,就像之前一样,"return" 子句会针对 "for" 循环中的每个项目进行计算,但与之前不同的是,现在您可以构建一个完整的 XML 子树,就像我们在下面的示例中将看到的。

FLWOR表达式中的`let`子句的目的是定义额外的变量,以便我们稍后可以使用这些变量来构建结果。这些变量可以来自相同的数据源,也可以来自不同的数据源。例如,可以使用循环变量从另一个数据源中选择特定的元素。

例如,假设一个数据源包含组织内部各个部门的信息,而另一个数据源包含员工信息,那么以下代码片段可能是一个 FLWOR 表达式的开头,用于从特定部门的员工列表中选择员工:

for $d in $DEPARTMENTS/depts/deptno
let $e := $EMPLOYEES/emps/emp[deptno = $d]

“where”子句允许我们根据特定条件筛选数据,这与我们之前在纯XPath表达式中使用谓词的方式类似。例如,我们可以使用它来根据员工数量筛选部门:

for $d in $DEPARTMENTS/depts/deptno
let $e := $EMPLOYEES/emps/emp[deptno = $d]
where count($e) >= 10

最后,`ORDER BY`子句允许我们按照任何想要的标准对结果进行排序,这在构建新的XML文档时尤其有用。

现在,让我们将前面提到的两个数据源(部门和员工)整合到整个 FLWOR 表达式中。例如,我们可以生成一个新的数据表,用于在移动解决方案中显示,该数据表将提供关于员工数量和平均工资的汇总信息,仅针对那些员工数量超过 10 个的部门。

for $d in $DEPARTMENTS/depts/deptno
let $e := $EMPLOYEES/emps/emp[deptno = $d]
where count($e) >= 10
order by avg($e/salary) descending
return
<big-dept>
   { $d,
      <headcount>{count($e)}</headcount>,
      <avgsal>{avg($e/salary)}</avgsal>
   }
</big-dept>

举另一个例子,利用我们之前关于包含明细项的手机账单的数据,现在我们可以进一步扩展功能,循环处理特定日期之后的多个账单,计算它们的总额,然后构建一个排序后的结果表格,我们可以按照总额从大到小进行展示,将总额最高的账单排在最前面,总额最小的账单排在最后。

for $inv in $DB1/sales/invoice
let $total := sum (for $x in item return $x/price * $x/quantity)
	where $inv/date >= "2014-01-01"
	order by $total descending
	return <invtotal>{ $total }</invtotal>

正如您所看到的,这些 XQuery 表达式的灵活性和功能远超我们过去仅使用 XPath 所能实现的效果。然而,更强大的功能也意味着更高的复杂性,因此可能需要一段时间才能完全掌握 XQuery。

同时,MobileTogether 内置的 XPath 和 XQuery 构建器和评估器可以极大地帮助您编写正确的表达式,并使用您的数据进行测试。 结合强大的模拟器,该模拟器允许您直接在 MobileTogether 设计器中运行您的移动应用程序,您可以轻松地使用 XPath 和 XQuery 测试和调试数据选择,并且比任何其他方法都能更快地构建强大的移动应用程序。

概要。

在本文档中,我们提供了一个关于 XPath 和 XQuery 最重要概念的简要介绍,旨在帮助您开始在 MobileTogether 中处理数据。我们介绍了 XPath 表达式的基本概念,以及 XQuery 的一些更强大的功能。这些内容应该能够帮助您在移动应用流程中进行强大的数据选择,精确地呈现您的数据图表,并根据具体的数据项,灵活地定制您的移动解决方案的用户界面。

然而,这份文档仅仅是一个起点,它并不旨在成为一份完整的教程,也不打算解释这些语言的每一个方面。您可以在我们的全面、免费的在线XPath培训课程中了解更多内容,该课程适合初学者以及高级用户。

MobileTogether 完整支持 XPath 3.0 和 XQuery 3.0 两种语言。使用国际标准,如 XPath 和 XQuery,的好处在于,很多开发者可能在过去处理 XML、XSLT 或 XML Schema 时已经学习过 XPath。因此,能够在 MobileTogether 中复用这些知识对他们来说是一大优势。而且,将您的知识从 XPath 1.0 或 2.0 升级到 3.0 是一个非常简单易行的过程。

此外,XPath和XQuery是由万维网联盟(W3C)制定的标准,而不是由某一家公司独创的专有语言,因此学习这些标准在其他领域也会有所帮助。

有关 XPath 3.0 和 XQuery 3.0 的完整规范,请参阅以下技术规范文档:

最后,但同样重要的一点是,在 MobileTogether 中使用 XPath 和 XQuery,意味着如果您需要进行更深入的开发,您可以轻松地使用 XMLSpy 来原型设计、开发和调试更复杂的 XPath 和 XQuery 表达式。XMLSpy 提供了完整的 XPath 评估器和 XQuery 调试器,包括用于性能优化的性能分析工具。

要了解更多关于 XPath 3.0 和 XQuery 3.0 的信息,请参考 Altova 的在线培训 和相关文档页面。我们还提供一份 XPath 参考手册,其中详细解释了所有 XPath 运算符和函数,并提供了使用示例。此外,您可以在 MobileTogether 的支持论坛 https://support.mobiletogether.com/ 上提出有关 XPath 和 XQuery 的问题。