http://www.softwareag.com/xml/library/xql-tutorial.htm
This tutorial discusses the simplest XQL queries, which are also likely to be the most common. In this tutorial, we will present a quick overview of XQL without taking the time to be precise.
A simple string is taken to be an element name. For instance, this query specification returns all <table> elements:table
The child operator ("/") indicates hierarchy. This query specification returns <author> elements that are children of <front> elements:front/author
The root of a document may be indicated by a leading "/" operator:/novel/front/author
Note: in XQL, the root of a document refers to the document entity, in the technical XML sense, which is basically equivalent to the document itself. It is not the same as the root element, which is the element that contains the rest of the elements in the document. The document root always contains the root element, but it may also contain a doctype, processing instructions, and comments. In this example, <novel> would be the root element.
Paths are always described from the top down, and unless otherwise specified, the right-most element on the path is returned. For instance, in the above example, <author> elements would be returned.
The content of an element or the value of an attribute may be specified using the equals operator ("="). The following returns all authors with the name "Theodore Seuss Geisel":front/author='Theodore Seuss Geisel'
Attribute names begin with "@". They are treated as children of the elements to which they belong:front/author/address/@type='email'
The descendant operator ("//") indicates any number of intervening levels. The following shows addresses anywhere within front:front//address
When the descendant operator is found at the start of a path, it means all nodes descended from the document. This query will find any address in the document://address
The filter operator ("[ ]") filters the set of nodes to its left based on the conditions inside the brackets. The following returns addresses. Each of these addresses must have an attribute called "type" with the value "email":front/author/address[@type='email']
Note that "address[@type='email']" returns addresses, but "address/@type='email'" returns type attributes.
Multiple conditions may be combined using Boolean operators.front/author='Theodore Seuss Geisel'[@gender='male' and @shoesize='9EEEE']
Brackets are also used for subscripts, which indicate position within a document. The following refers to sections 0, 3, 4, 5, and 8, plus the last section:section[0, 3 to 5, 8, -1]
Conditions and subscripts may not both occur in the same brackets, but both uses of brackets may occur in the same query. The following refers to the first three sections whose level attributes have the value "3"; in other words, it returns the first three "level 3" sections:section[@level='3'][0 to 2]
Now that we know the basics, let's take a look at a document and try some XQL queries on it. The following is an invoice document. Traditionally, invoices are often stored in databases, but invoices are both documents and data. XQL is designed to work on both documents and data, provided they are represented via XML through some interface. This document will be the basis for the sample queries that follow:<?xml version="1.0"?>
<invoicecollection>
<invoice>
<customer>
Wile E. Coyote, Death Valley, CA
</customer>
<annotation>
Customer asked that we guarantee
return rights if these items
should fail in desert conditions.
This was approved by Marty
Melliore, general manager.
</annotation>
<entries n=2>
<entry quantity=2 total_price="134.00">
<product maker="ACME" prod_name="screwdriver"
price="80.00"/>
</entry>
<entry quantity=1 total_price="20.00">
<product maker="ACME" prod_name="power wrench"
price="20.00"/>
</entry>
</entries>
</invoice>
<invoice>
<customer>
Camp Mertz
</customer>
<entries n=2>
<entry quantity=2 total_price="32.00">
<product maker="BSA" prod_name="
left-handed smoke shifter" price="16.00"/>
</entry>
<entry quantity=1 total_price="13.00">
<product maker="BSA" prod_name="snipe call"
price="13.00"/>
</entry>
</entries>
</invoice>
</invoicecollection>
Now let's look at some sample queries. Suppose we wanted to see just the customers from the database. We could do the following query:Query:
//customer
Result:
<xql:result>
<customer>
Wile E. Coyote, Death Valley, CA
</customer>
<customer>
Camp Mertz
</customer>
</xql:result>
We might want to look at all the products manufactured by BSA. This query would do the trick:Query:
//product[@maker='BSA']
Result:
<xql:result>
<product maker="BSA" prod_name="left-handed
smoke shifter" price="16.00"/>
<product maker="BSA" prod_name="snipe call"
price="13.00"/>
</xql:result>
Filters are very useful when specifying conditions on paths that are not the same as what is returned. For instance, the following query returns the products ordered by Camp Mertz:Query:
//invoice[customer='Wile E. Coyote, Death Valley,
CA']//
product
Result:
<xql:result>
<product maker="ACME" prod_name="screwdriver"
price="80.00"/>
<product maker="ACME" prod_name="power wrench"
price="20.00"/>
</xql:result>
http://bbs.xml.org.cn/dispbbs.asp?boardID=17&ID=8386
XML查询语言(XQL) 是用于定位和过滤XML文档中元素和文本的符号。它是XSL模式语法的自然扩展,为指向特定的元素或查找具有指定特征的节点提供了简明的可以理解的符号。XQL是最早由Microsoft,Texcel等公司提出的一种XML查询语言,前面我们已经提到,XSL模式语言提供了一种描述一类将需要处理的结点的好方法。实际上是通过XPath来实现的,当然XSL是说明性的,而非过程性的。但XSL也有许多不足之处,如不支持表达式,不能在结点间进行等值连接,对多个分散的XSL文档没有一个形式化的查询机制,没有支持聚集操作等。XQL则在XSL基础上提供了筛选操作,布尔操作,对结点集进行索引,并为查询、定位等提供了单一的语法形式。因而在一定意义上可将XQL看作XSL的超集。
XQL主要针对解决以下四个问题域而提出:
(1)在单个XML文档中进行查询。如在XML浏览器和编辑器中对所处理的XML文档进行查询。另外, Script也能利用这种性质给出一个非过程性的存取文档数据和结构的方法。
(2)在XML文档集中进行查询。如在XML文档仓储(Repository)中进行查询。
(3)能在XML文档间对结点进行定位。在HTML文档中,常常用HyperLink来定位其它文档,而在已有的XML中,链接形式更多样化,有TEL Links, HyTime Links,XML Linking,这些都允许链接有更大的灵活性。XQL则主要是想通过给出一已知位置的相对路径,或通过一绝对路径来在文档中定位任一结点。
(4)以字符串语法形式表达,使其能在URL中应用在XSL模板中及其它地方应用。
在介绍例子查询之前,对XQL中的一个重要的概念:Context 作一了解。Context即查询指定的一系列结点。XQL的基本语法模仿了URI(Unified Resource Identifier)目录导航语法,通过Context,XQL可以指定XQL查询是以XML树结构中哪一层开设作为查询范围(例如,从树的根结点或儿子结点)。XQL中以 / 表示根环境(Root context),以./ 表示当前环境(Current context)。
XQL简单例子及分析
举一个具体的例子来说明XML的应用,首先我们来建立一个如下的XML文档:
<?xml version="1.0" encoding="GB2312" ?>
<订单集合>
<订单>
<客户>
美博进出口公司
</客户>
<注释>
主要用来进出口各种办公用具:包括各种笔盒、本子、笔等等。
</注释>
<清单列表 n=2>
<清单 数量=100 总金额="24.00">
<产品 标记="STA" 名称="铅笔" 价格="0.24"/>
</清单>
<清单 数量=200 总金额="120.00">
<产品 标记="STA" 名称="钢笔" 价格="0.60"/>
</清单>
</清单列表>
</订单>
<订单>
<客户>
金鼎进出口公司
</客户>
<注释>
主要用来进出口各种化妆用具:包括各种眉笔、口红、护肤霜等等。
</注释>
<清单列表 n=2>
<清单 数量=100 总金额="124.00">
<产品 标记="BMA" 名称="眉笔" 价格="1.24"/>
</清单>
<清单 数量=200 总金额="720.00">
<产品 标记="BMA" 名称="口红" 价格="3.60"/>
</清单>
</清单列表>
</订单>
</订单集合>
下面我们来建立几个实际的查询例子,根据我们在XPath中的学习的经验可以知道,元素集合可以用路径操作符("/"或"//")指定。路径操作符将左部作为查询来源的参数集合,右部表示需要查询的元素。子女操作符("/")查询左部元素集合的直接子女集合,后代操作符("//")查询左部元素集合的任意后代集合。
例子1:
查询:
file://客户
结果:
<xql:result>
<客户>
美博进出口公司
</客户>
<客户>
金鼎进出口公司
</客户>
</xql:result>
我们知道,属性名称用"@"符号开头。XQL设计公平对待属性和子元素,在可能的情况下,两种类型的能力是等价的。注意:属性不能包含子元素。因此,在查询中属性不能使用路径操作符。否则将导致语法错误。同样地,属性天生没有顺序,索引不能用于属性。
通过对集合增加过滤子句"[ ]",可以对任何集合进行限制和分枝。过滤是SQL中包含ANY语义的WHERE子句的模拟。过滤子句中包含了一个查询,称为子查询。子查询计算出布尔值,对集合中的每一个元素进行测试。集合中未通过子查询测试的元素将从结果集合中省略。为方便起见,如果集合放于过滤之中,或者如果集合中包含元素,则产生布尔值TRUE;如果集合为空,则产生FALSE。本质上,如author/degree的表达式表示集合到布尔值的转换函数,象如下虚构的"存在一个"方法:
author[.there-exists-a(degree)]
注意,在表达式的给定级别上可以出现任何数目的过滤,但空过滤是不允许的。同时需要注意的是,在XQL语言中,"=" 符号用于相等判断,"!="用于不相等判断。作为选择,$eq$和$ne$ 也可用于相等和不相等。单引号或双引号可以用于在表达式中分隔字符串,使得在脚本语言中创建或传递XQL变得更为容易。
对于比较元素值而言,暗含了value()方法。也就是说,last-name < 'foo'实际上表示last-name!value() < foo。这有点象VB中对对象指定缺省的属性一样,比如一个Text对象Text1,Text1="中国"相当于Text1.text="中国"。
请注意,过滤总是和上下文相关的。即:表达式book[author]表示对每一个找到的book元素,查看其是否包含author子元素。同样地,book[author = Bob ] 表示对每一个找到的book元素,查看其是否包含命名为author,且值为'Bob'的子元素。你也可以通过使用"."(句点) 查看当前上下文的值。例如,book[. ='古龙' ]表示对每一个找到的book元素,查看其值是否等于'古龙'。
例子2:
查询
file://产品[@标记='BMA']
结果:
<xql:result>
<产品 标记="BMA" 名称="眉笔" 价格="1.24"/>
<产品 标记="BMA" 名称="口红" 价格="3.60"/>
</xql:result>
例子3:
file://订单[客户='美博进出口公司']/产品
结果:
<xql:result>
<产品 标记="STA" 名称="铅笔" 价格="0.24"/>
<产品 标记="STA" 名称="钢笔" 价格="0.60"/>
</xql:result>
布尔表达式可以在子查询中使用。例如,可以使用布尔表达式查找特定值的节点集合,或者特定范围的节点集合。布尔表达式采取${op}$的形式,而{op}可以是任何{b|a}形式的表达式-即:操作符接收左值和右值参数,返回布尔结果。应用可以根据需要提供附加的布尔操作符。
例子4:
查询
file://产品[@标记='BMA'|@标记='STA']
结果:
<xql:result>
<产品 标记="STA" 名称="铅笔" 价格="0.24"/>
<产品 标记="STA" 名称="钢笔" 价格="0.60"/>
<产品 标记="BMA" 名称="眉笔" 价格="1.24"/>
<产品 标记="BMA" 名称="口红" 价格="3.60"/>
</xql:result>
这里,我们需要从上面的例子入手来描述XQL的语法特点,首先需要注意的是,XQL表达式返回的集合在定义范围内保持文档顺序,层次结构和标识。即:元素集合总是无重复地以文档顺序返回,属性集合将无重复地返回,但由于属性无顺序地定义,返回集合并不意味着顺序。