1 =head1 NAME |
|
2 |
|
3 XML::XQL::Tutorial - Describes the XQL query syntax |
|
4 |
|
5 =head1 DESCRIPTION |
|
6 |
|
7 This document describes basic the features of the XML Query Language (XQL.) |
|
8 A proposal for the XML Query Language (XQL) specification was submitted |
|
9 to the XSL Working Group in September 1998. |
|
10 The spec can be found at L<http://www.w3.org/TandS/QL/QL98/pp/xql.html>. |
|
11 Since it is only a proposal at this point, things may change, but it is very |
|
12 likely that the final version will be close to the proposal. |
|
13 Most of this document was copied straight from the spec. |
|
14 |
|
15 See also the L<XML::XQL> man page. |
|
16 |
|
17 =head1 INTRODUCTION |
|
18 |
|
19 XQL (XML Query Language) provides a natural extension to the XSL pattern |
|
20 language. It builds upon the capabilities XSL provides for identifying classes |
|
21 of nodes, by adding Boolean logic, filters, indexing into collections of nodes, |
|
22 and more. |
|
23 |
|
24 XQL is designed specifically for XML documents. |
|
25 It is a general purpose query language, providing a single syntax |
|
26 that can be used for queries, addressing, and patterns. |
|
27 XQL is concise, simple, and powerful. |
|
28 |
|
29 XQL is designed to be used in many contexts. Although it is a superset of XSL |
|
30 patterns, it is also applicable to providing links to nodes, for searching |
|
31 repositories, and for many other applications. |
|
32 |
|
33 Note that the term XQL is a working term for the language described in this |
|
34 proposal. It is not their intent that this term be used permanently. |
|
35 Also, beware that another query language exists called XML-QL, |
|
36 which uses a syntax very similar to SQL. |
|
37 |
|
38 The L<XML::XQL> module has added functionality to the XQL spec, called I<XQL+>. |
|
39 To allow only XQL functionality as described in the spec, use the |
|
40 XML::XQL::Strict module. Note that the XQL spec makes the distinction between |
|
41 core XQL and XQL extensions. This implementation makes no distinction and |
|
42 the Strict module, therefore, implements everything described in the XQL spec. |
|
43 See the L<XML::XQL> man page for more information about the Strict module. |
|
44 This tutorial will clearly indicate when referring to XQL+. |
|
45 |
|
46 =head1 XQL Patterns |
|
47 |
|
48 This section describes the core XQL notation. These features should be part |
|
49 of every XQL implementation, and serve as the base level of functionality |
|
50 for its use in different technologies. |
|
51 |
|
52 The basic syntax for XQL mimics the URI directory navigation syntax, but |
|
53 instead of specifying navigation through a |
|
54 physical file structure, the navigation is through elements in the XML tree. |
|
55 |
|
56 For example, the following URI means find the foo.jpg file within the bar |
|
57 directory: |
|
58 |
|
59 bar/foo.jpg |
|
60 |
|
61 Similarly, in XQL, the following means find the collection of fuz elements |
|
62 within baz elements: |
|
63 |
|
64 baz/fuz |
|
65 |
|
66 Throughout this document you will find numerous samples. They refer to the data |
|
67 shown in the sample file at the end of this man page. |
|
68 |
|
69 =head1 Context |
|
70 |
|
71 A I<context> is the set of nodes against which a query operates. |
|
72 For the entire query, which is passed to the L<XML::XQL::Query> |
|
73 constructor through the I<Expr> option, the context is the list of input nodes |
|
74 that is passed to the query() method. |
|
75 |
|
76 XQL allows a query to select between using the current context as the input |
|
77 context and using the 'root context' as the input context. |
|
78 The 'root context' is a context containing only the root-most |
|
79 element of the document. When using XML::DOM, this is the Document object. |
|
80 |
|
81 By default, a query uses the current context. A query prefixed with '/' |
|
82 (forward slash) uses the root context. A query may |
|
83 optionally explicitly state that it is using the current context by using |
|
84 the './' (dot, forward slash) prefix. Both of these |
|
85 notations are analogous to the notations used to navigate directories in a file |
|
86 system. |
|
87 |
|
88 The './' prefix is only required in one situation. A query may use the '//' |
|
89 operator to indicate recursive descent. When |
|
90 this operator appears at the beginning of the query, the initial '/' causes the |
|
91 recursive decent to perform relative to the |
|
92 root of the document or repository. The prefix './/' allows a query to perform |
|
93 a recursive descent relative to the current context. |
|
94 |
|
95 =over 4 |
|
96 |
|
97 =item Examples: |
|
98 |
|
99 Find all author elements within the current context. Since the period is really |
|
100 not used alone, this example forward-references other features: |
|
101 |
|
102 ./author |
|
103 |
|
104 Note that this is equivalent to: |
|
105 |
|
106 author |
|
107 |
|
108 Find the root element (bookstore) of this document: |
|
109 |
|
110 /bookstore |
|
111 |
|
112 Find all author elements anywhere within the current document: |
|
113 |
|
114 //author |
|
115 |
|
116 Find all books where the value of the style attribute on the book is equal to |
|
117 the value of the specialty attribute of the bookstore element at the root of |
|
118 the document: |
|
119 |
|
120 book[/bookstore/@specialty = @style] |
|
121 |
|
122 =back |
|
123 |
|
124 =head1 Query Results |
|
125 |
|
126 The collection returned by an XQL expression preserves document order, |
|
127 hierarchy, and identity, to the extent that these are defined. |
|
128 That is, a collection of elements will always be returned in document order |
|
129 without repeats. Note that the spec states that the order of attributes within |
|
130 an element is undefined, but that this implementation does keep attributes |
|
131 in document order. See the L<XML::XQL> man page for more details regarding |
|
132 I<Document Order>. |
|
133 |
|
134 =head1 Collections - 'element' and '.' |
|
135 |
|
136 The collection of all elements with a certain tag name is expressed using the |
|
137 tag name itself. This can be qualified by showing that the elements are |
|
138 selected from the current context './', but the current context is assumed and |
|
139 often need not be noted explicitly. |
|
140 |
|
141 =over 4 |
|
142 |
|
143 =item Examples: |
|
144 |
|
145 Find all first-name elements. These examples are equivalent: |
|
146 |
|
147 ./first-name |
|
148 |
|
149 first-name |
|
150 |
|
151 Find all unqualified book elements: |
|
152 |
|
153 book |
|
154 |
|
155 Find all first.name elements: |
|
156 |
|
157 first.name |
|
158 |
|
159 =back |
|
160 |
|
161 =head1 Selecting children and descendants - '/' and '//' |
|
162 |
|
163 The collection of elements of a certain type can be determined using the path |
|
164 operators ('/' or '//'). These operators take as their arguments a collection |
|
165 (left side) from which to query elements, and a collection indicating which |
|
166 elements to select (right side). The child operator ('/')selects from immediate |
|
167 children of the left-side collection, while the descendant operator ('//') |
|
168 selects from arbitrary descendants of the left-side collection. |
|
169 In effect, the '//' can be thought of as a substitute for one or more levels of |
|
170 hierarchy. Note that the path operators change the context as the |
|
171 query is performed. By stringing them together users can 'drill down' into the |
|
172 document. |
|
173 |
|
174 =over 4 |
|
175 |
|
176 =item Examples: |
|
177 |
|
178 Find all first-name elements within an author element. Note that the author |
|
179 children of the current context are found, and then first-name children are |
|
180 found relative to the context of the author elements: |
|
181 |
|
182 author/first-name |
|
183 |
|
184 Find all title elements, one or more levels deep in the bookstore |
|
185 (arbitrary descendants): |
|
186 |
|
187 bookstore//title |
|
188 |
|
189 Note that this is different from the following query, which finds all title |
|
190 elements that are grandchildren of bookstore elements: |
|
191 |
|
192 bookstore/*/title |
|
193 |
|
194 Find emph elements anywhere inside book excerpts, anywhere inside the bookstore: |
|
195 |
|
196 bookstore//book/excerpt//emph |
|
197 |
|
198 Find all titles, one or more levels deep in the current context. Note that this |
|
199 situation is essentially the only one where |
|
200 the period notation is required: |
|
201 |
|
202 .//title |
|
203 |
|
204 =back |
|
205 |
|
206 =head1 Collecting element children - '*' |
|
207 |
|
208 An element can be referenced without using its name by substituting the '*' |
|
209 collection. The '*' collection returns all |
|
210 elements that are children of the current context, regardless of their tag name. |
|
211 |
|
212 =over 4 |
|
213 |
|
214 =item Examples: |
|
215 |
|
216 Find all element children of author elements: |
|
217 |
|
218 author/* |
|
219 |
|
220 Find all last-names that are grand-children of books: |
|
221 |
|
222 book/*/last-name |
|
223 |
|
224 Find the grandchildren elements of the current context: |
|
225 |
|
226 */* |
|
227 |
|
228 Find all elements with specialty attributes. Note that this example uses |
|
229 subqueries, which are covered in Filters, and |
|
230 attributes, which are discussed in Finding an attribute: |
|
231 |
|
232 *[@specialty] |
|
233 |
|
234 =back |
|
235 |
|
236 =head1 Finding an attribute - '@' |
|
237 |
|
238 Attribute names are preceded by the '@' symbol. XQL is designed to treat |
|
239 attributes and sub-elements impartially, |
|
240 and capabilities are equivalent between the two types wherever possible. |
|
241 |
|
242 Note: attributes cannot contain subelements. Thus, attributes cannot have path |
|
243 operators applied to them in a query. |
|
244 Such expressions will result in a syntax error. |
|
245 The XQL spec states that attributes are inherently unordered and indices |
|
246 cannot be applied to them, but this implementation allows it. |
|
247 |
|
248 =over 4 |
|
249 |
|
250 =item Examples: |
|
251 |
|
252 Find the style attribute of the current element context: |
|
253 |
|
254 @style |
|
255 |
|
256 Find the exchange attribute on price elements within the current context: |
|
257 |
|
258 price/@exchange |
|
259 |
|
260 The following example is not valid: |
|
261 |
|
262 price/@exchange/total |
|
263 |
|
264 Find all books with style attributes. Note that this example uses subqueries, |
|
265 which are covered in Filters: |
|
266 |
|
267 book[@style] |
|
268 |
|
269 Find the style attribute for all book elements: |
|
270 |
|
271 book/@style |
|
272 |
|
273 =back |
|
274 |
|
275 =head1 XQL Literals |
|
276 |
|
277 XQL query expressions may contain literal values (i.e. constants.) |
|
278 Numbers (integers and floats) are wrapped in XML::XQL::Number objects and |
|
279 strings in XML::XQL::Text objects. Booleans (as returned by true() and false()) |
|
280 are wrapped in XML::XQL::Boolean objects. |
|
281 |
|
282 Strings must be enclosed in single or double quotes. Since XQL does not allow |
|
283 escaping of special characters, it's impossible to create a string with both |
|
284 a single and a double quote in it. To remedy this, XQL+ has added the q// and |
|
285 qq// string delimiters which behave just like they do in Perl. |
|
286 |
|
287 For Numbers, exponential notation is not allowed. Use the XQL+ function eval() |
|
288 to circumvent this problem. See L<XML::XQL> man page for details. |
|
289 |
|
290 The empty list or undef is represented by [] (i.e. reference to empty array) |
|
291 in this implementation. |
|
292 |
|
293 =over 4 |
|
294 |
|
295 =item Example |
|
296 |
|
297 Integer Numbers: |
|
298 |
|
299 234 |
|
300 -456 |
|
301 |
|
302 Floating point Numbers: |
|
303 |
|
304 1.23 |
|
305 -0.99 |
|
306 |
|
307 Strings: |
|
308 |
|
309 "some text with 'single' quotes" |
|
310 'text with "double" quotes' |
|
311 |
|
312 Not allowed: |
|
313 |
|
314 1.23E-4 (use eval("1.23E-4", "Number") in XQL+) |
|
315 |
|
316 "can't use \"double \"quotes" (use q/can't use "double" quotes/ in XQL+) |
|
317 |
|
318 =back |
|
319 |
|
320 =head1 Grouping - '()' |
|
321 |
|
322 Parentheses can be used to group collection operators for clarity or where the |
|
323 normal precedence is inadequate to express an operation. |
|
324 |
|
325 =head1 Filters - '[]' |
|
326 |
|
327 Constraints and branching can be applied to any collection by adding a filter |
|
328 clause '[ ]' to the collection. The filter is analogous to the SQL WHERE clause |
|
329 with ANY semantics. The filter contains a query within it, called the |
|
330 subquery. The subquery evaluates to a Boolean, and is tested for each element |
|
331 in the collection. Any elements in the collection failing the subquery test are |
|
332 omitted from the result collection. |
|
333 |
|
334 For convenience, if a collection is placed within the filter, a Boolean TRUE |
|
335 is generated if the collection contains any members, and a FALSE is generated |
|
336 if the collection is empty. In essence, an expression such as author/degree |
|
337 implies a collection-to-Boolean conversion function like the following |
|
338 mythical 'there-exists-a' method. |
|
339 |
|
340 author[.there-exists-a(degree)] |
|
341 |
|
342 Note that any number of filters can appear at a given level of an expression. |
|
343 Empty filters are not allowed. |
|
344 |
|
345 =over 4 |
|
346 |
|
347 =item Examples: |
|
348 |
|
349 Find all books that contain at least one excerpt element: |
|
350 |
|
351 book[excerpt] |
|
352 |
|
353 Find all titles of books that contain at least one excerpt element: |
|
354 |
|
355 book[excerpt]/title |
|
356 |
|
357 Find all authors of books where the book contains at least one excerpt, and |
|
358 the author has at least one degree: |
|
359 |
|
360 book[excerpt]/author[degree] |
|
361 |
|
362 Find all books that have authors with at least one degree: |
|
363 |
|
364 book[author/degree] |
|
365 |
|
366 Find all books that have an excerpt and a title: |
|
367 |
|
368 book[excerpt][title] |
|
369 |
|
370 =back |
|
371 |
|
372 =head2 Any and all semantics - '$any$' and '$all$' |
|
373 |
|
374 Users can explicitly indicate whether to use any or all semantics through |
|
375 the $any$ and $all$ keywords. |
|
376 |
|
377 $any$ flags that a condition will hold true if any item in a set meets that |
|
378 condition. $all$ means that all elements in a |
|
379 set must meet the condition for the condition to hold true. |
|
380 |
|
381 $any$ and $all$ are keywords that appear before a subquery expression within |
|
382 a filter. |
|
383 |
|
384 =over 4 |
|
385 |
|
386 =item Examples: |
|
387 |
|
388 Find all author elements where one of the last names is Bob: |
|
389 |
|
390 author[last-name = 'Bob'] |
|
391 |
|
392 author[$any$ last-name = 'Bob'] |
|
393 |
|
394 Find all author elements where none of the last-name elements are Bob: |
|
395 |
|
396 author[$all$ last-name != 'Bob'] |
|
397 |
|
398 Find all author elements where the first last name is Bob: |
|
399 |
|
400 author[last-name[0] = 'Bob'] |
|
401 |
|
402 =back |
|
403 |
|
404 =head1 Indexing into a collection - '[]' and '$to$' |
|
405 |
|
406 XQL makes it easy to find a specific node within a set of nodes. |
|
407 Simply enclose the index ordinal within square brackets. The ordinal is 0 based. |
|
408 |
|
409 A range of elements can be returned. To do so, specify an expression rather |
|
410 than a single value inside of the subscript operator (square brackets). |
|
411 Such expressions can be a comma separated list of any of the following: |
|
412 |
|
413 n Returns the nth element |
|
414 -n Returns the element that is n-1 units from the last element. |
|
415 E.g., -1 means the last element. -2 is the next to last element. |
|
416 m $to$ n Returns elements m through n, inclusive |
|
417 |
|
418 =over 4 |
|
419 |
|
420 =item Examples: |
|
421 |
|
422 Find the first author element: |
|
423 |
|
424 author[0] |
|
425 |
|
426 Find the third author element that has a first-name: |
|
427 |
|
428 author[first-name][2] |
|
429 |
|
430 Note that indices are relative to the parent. In other words, consider the |
|
431 following data: |
|
432 |
|
433 <x> |
|
434 <y/> |
|
435 <y/> |
|
436 </x> |
|
437 <x> |
|
438 <y/> |
|
439 <y/> |
|
440 </x> |
|
441 |
|
442 The following expression will return the first y from each of the x's: |
|
443 |
|
444 x/y[0] |
|
445 |
|
446 The following will return the first y from the entire set of y's within x's: |
|
447 |
|
448 (x/y)[0] |
|
449 |
|
450 The following will return the first y from the first x: |
|
451 |
|
452 x[0]/y[0] |
|
453 |
|
454 Find the first and fourth author elements: |
|
455 |
|
456 author[0,3] |
|
457 |
|
458 Find the first through fourth author elements: |
|
459 |
|
460 author[0 $to$ 3] |
|
461 |
|
462 Find the first, the third through fifth, and the last author elements: |
|
463 |
|
464 author[0, 2 $to$ 4, -1] |
|
465 |
|
466 Find the last author element: |
|
467 |
|
468 author[-1] |
|
469 |
|
470 =back |
|
471 |
|
472 =head1 Boolean Expressions |
|
473 |
|
474 Boolean expressions can be used within subqueries. For example, one could use |
|
475 Boolean expressions to find all nodes of a particular value, or all nodes with |
|
476 nodes in particular ranges. Boolean expressions are of the form |
|
477 ${op}$, where {op} may be any expression of the form {b|a} - that is, the |
|
478 operator takes lvalue and rvalue arguments and returns a Boolean result. |
|
479 |
|
480 Note that the XQL Extensions section defines additional Boolean operations. |
|
481 |
|
482 =head2 Boolean AND and OR - '$and$' and '$or$' |
|
483 |
|
484 $and$ and $or$ are used to perform Boolean ands and ors. |
|
485 |
|
486 The Boolean operators, in conjunction with grouping parentheses, can be used to |
|
487 build very sophisticated logical expressions. |
|
488 |
|
489 Note that spaces are not significant and can be omitted, or included for |
|
490 clarity as shown here. |
|
491 |
|
492 =over 4 |
|
493 |
|
494 =item Examples: |
|
495 |
|
496 Find all author elements that contain at least one degree and one award. |
|
497 |
|
498 author[degree $and$ award] |
|
499 |
|
500 Find all author elements that contain at least one degree or award and at |
|
501 least one publication. |
|
502 |
|
503 author[(degree $or$ award) $and$ publication] |
|
504 |
|
505 =back |
|
506 |
|
507 =head2 Boolean NOT - '$not$' |
|
508 |
|
509 $not$ is a Boolean operator that negates the value of an expression within a |
|
510 subquery. |
|
511 |
|
512 =over 4 |
|
513 |
|
514 =item Examples: |
|
515 |
|
516 Find all author elements that contain at least one degree element and that |
|
517 contain no publication elements. |
|
518 |
|
519 author[degree $and$ $not$ publication] |
|
520 |
|
521 Find all author elements that contain publications elements but do not contain |
|
522 either degree elements or award elements. |
|
523 |
|
524 author[$not$ (degree $or$ award) $and$ publication] |
|
525 |
|
526 =back |
|
527 |
|
528 =head1 Union and intersection - '$union$', '|' and '$intersect$' |
|
529 |
|
530 The $union$ operator (shortcut is '|') returns the combined set of values from |
|
531 the query on the left and the query on the right. Duplicates are filtered out. |
|
532 The resulting list is sorted in document order. |
|
533 |
|
534 Note: because this is a union, the set returned may include 0 or more elements |
|
535 of each element type in the list. To restrict the returned set to nodes that |
|
536 contain at least one of each of the elements in the list, use a filter, as |
|
537 discussed in Filters. |
|
538 |
|
539 The $intersect$ operator returns the set of elements in common between two sets. |
|
540 |
|
541 =over 4 |
|
542 |
|
543 =item Examples: |
|
544 |
|
545 Find all first-names and last-names: |
|
546 |
|
547 first-name $union$ last-name |
|
548 |
|
549 Find all books and magazines from a bookstore: |
|
550 |
|
551 bookstore/(book | magazine) |
|
552 |
|
553 Find all books and all authors: |
|
554 |
|
555 book $union$ book/author |
|
556 |
|
557 Find the first-names, last-names, or degrees from authors within either books |
|
558 or magazines: |
|
559 |
|
560 (book $union$ magazine)/author/(first-name $union$ last-name $union$ degree) |
|
561 |
|
562 Find all books with author/first-name equal to 'Bob' and all magazines with |
|
563 price less than 10: |
|
564 |
|
565 book[author/first-name = 'Bob'] $union$ magazine[price $lt$ 10] |
|
566 |
|
567 =back |
|
568 |
|
569 =head1 Equivalence - '$eq$', '=', '$ne$' and '!=' |
|
570 |
|
571 The '=' sign is used for equality; '!=' for inequality. Alternatively, $eq$ and |
|
572 $ne$ can be used for equality and inequality. |
|
573 |
|
574 Single or double quotes can be used for string delimiters in expressions. |
|
575 This makes it easier to construct and pass XQL from within scripting languages. |
|
576 |
|
577 For comparing values of elements, the value() method is implied. That is, |
|
578 last-name < 'foo' really means last-name!value() < 'foo'. |
|
579 |
|
580 Note that filters are always with respect to a context. That is, the expression |
|
581 book[author] means for every book element that is found, see if it has an |
|
582 author subelement. Likewise, book[author = 'Bob'] means for |
|
583 every book element that is found, see if it has a subelement named author |
|
584 whose value is 'Bob'. One can examine the value of the context as well, by |
|
585 using the . (period). For example, book[. = 'Trenton'] means for every |
|
586 book that is found, see if its value is 'Trenton'. |
|
587 |
|
588 =over 4 |
|
589 |
|
590 =item Examples: |
|
591 |
|
592 Find all author elements whose last name is Bob: |
|
593 |
|
594 author[last-name = 'Bob'] |
|
595 |
|
596 author[last-name $eq$ 'Bob'] |
|
597 |
|
598 Find all authors where the from attribute is not equal to 'Harvard': |
|
599 |
|
600 degree[@from != 'Harvard'] |
|
601 |
|
602 degree[@from $ne$ 'Harvard'] |
|
603 |
|
604 Find all authors where the last-name is the same as the /guest/last-name element: |
|
605 |
|
606 author[last-name = /guest/last-name] |
|
607 |
|
608 Find all authors whose text is 'Matthew Bob': |
|
609 |
|
610 author[. = 'Matthew Bob'] |
|
611 |
|
612 author = 'Matthew Bob' |
|
613 |
|
614 =back |
|
615 |
|
616 =head2 Comparison - '<', '<=', '>', '>=', '$lt', '$ilt$' etc. |
|
617 |
|
618 A set of binary comparison operators is available for comparing numbers and |
|
619 strings and returning Boolean results. |
|
620 $lt$, $le$, $gt$, $ge$ are used for less than, less than or equal, greater |
|
621 than, or greater than or equal. These same |
|
622 operators are also available in a case insensitive form: $ieq$, $ine$, $ilt$, |
|
623 $ile$, $igt$, $ige$. |
|
624 |
|
625 <, <=, > and >= are allowed short cuts for $lt$, $le$, $gt$ and $ge$. |
|
626 |
|
627 =over 4 |
|
628 |
|
629 =item Examples: |
|
630 |
|
631 Find all author elements whose last name is bob and whose price is > 50 |
|
632 |
|
633 author[last-name = 'Bob' $and$ price $gt$ 50] |
|
634 |
|
635 Find all authors where the from attribute is not equal to 'Harvard': |
|
636 |
|
637 degree[@from != 'Harvard'] |
|
638 |
|
639 Find all authors whose last name begins with 'M' or greater: |
|
640 |
|
641 author[last-name $ge$ 'M'] |
|
642 |
|
643 Find all authors whose last name begins with 'M', 'm' or greater: |
|
644 |
|
645 author[last-name $ige$ 'M'] |
|
646 |
|
647 Find the first three books: |
|
648 |
|
649 book[index() $le$ 2] |
|
650 |
|
651 Find all authors who have more than 10 publications: |
|
652 |
|
653 author[publications!count() $gt$ 10] |
|
654 |
|
655 =back |
|
656 |
|
657 =head2 XQL+ Match operators - '$match$', '$no_match$', '=~' and '!~' |
|
658 |
|
659 XQL+ defines additional operators for pattern matching. The $match$ operator |
|
660 (shortcut is '=~') returns TRUE if the lvalue matches the pattern described by |
|
661 the rvalue. The $no_match$ operator (shortcut is '!~') returns FALSE if they |
|
662 match. Both lvalue and rvalue are first cast to strings. |
|
663 |
|
664 The rvalue string should have the syntax of a Perl rvalue, that is the delimiters |
|
665 should be included and modifiers are allowed. When using delimiters other than |
|
666 slashes '/', the 'm' should be included. The rvalue should be a string, so don't |
|
667 forget the quotes! (Or use the q// or qq// delimiters in XQL+, see L<XML::XQL> |
|
668 man page.) |
|
669 |
|
670 Note that you can't use the Perl substitution operator s/// here. Try using the |
|
671 XQL+ subst() function instead. |
|
672 |
|
673 =over 4 |
|
674 |
|
675 =item Examples: |
|
676 |
|
677 Find all authors whose name contains bob or Bob: |
|
678 |
|
679 author[first-name =~ '/[Bb]ob/'] |
|
680 |
|
681 Find all book titles that don't contain 'Trenton' (case-insensitive): |
|
682 |
|
683 book[title !~ 'm!trenton!i'] |
|
684 |
|
685 =back |
|
686 |
|
687 =head2 Oher XQL+ comparison operators - '$isa', '$can$' |
|
688 |
|
689 See the L<XML::XQL> man page for other operators available in XQL+. |
|
690 |
|
691 =head2 Comparisons and vectors |
|
692 |
|
693 The lvalue of a comparison can be a vector or a scalar. The rvalue of a |
|
694 comparison must be a scalar or a value that can be cast at runtime to a scalar. |
|
695 |
|
696 If the lvalue of a comparison is a set, then any (exists) semantics are used |
|
697 for the comparison operators. That is, the result of a comparison is true if |
|
698 any item in the set meets the condition. |
|
699 |
|
700 =head2 Comparisons and literals |
|
701 |
|
702 The spec states that the lvalue of an expression cannot be a literal. |
|
703 That is, I<'1' = a> is not allowed. This implementation allows it, but it's not |
|
704 clear how useful that is. |
|
705 |
|
706 =head2 Casting of literals during comparison |
|
707 |
|
708 Elements, attributes and other XML node types are casted to strings (Text) |
|
709 by applying the value() method. The value() method calls the text() method by |
|
710 default, but this behavior can be altered by the user, so the value() method |
|
711 may return other XQL data types. |
|
712 |
|
713 When two values are compared, they are first casted to the same type. |
|
714 See the L<XML::XQL> man page for details on casting. |
|
715 |
|
716 Note that the XQL spec is not very clear on how values should be casted for |
|
717 comparison. Discussions with the authors of the XQL spec revealed that there |
|
718 was some disagreement and their implementations differed on this point. |
|
719 This implementation is closest to that of Joe Lapp from webMethods, Inc. |
|
720 |
|
721 =head1 Methods - 'method()' or 'query!method()' |
|
722 |
|
723 XQL makes a distinction between functions and methods. |
|
724 See the L<XML::XQL> man page for details. |
|
725 |
|
726 XQL provides methods for advanced manipulation of collections. These methods |
|
727 provide specialized collections of nodes (see Collection methods), as well as |
|
728 information about sets and nodes. |
|
729 |
|
730 Methods are of the form I<method(arglist)> |
|
731 |
|
732 Consider the query book[author]. It will find all books that have authors. |
|
733 Formally, we call the book corresponding to a particular author the reference |
|
734 node for that author. That is, every author element that is examined is an author |
|
735 for one of the book elements. (See the Annotated XQL BNF Appendix for a much |
|
736 more thorough definition of reference node and other terms. See also the |
|
737 XML::XQL man page.) Methods always apply to the reference node. |
|
738 |
|
739 For example, the text() method returns the text contained within a node, |
|
740 minus any structure. (That is, it is the concatenation of all text nodes |
|
741 contained with an element and its descendants.) The following expression will |
|
742 return all authors named 'Bob': |
|
743 |
|
744 author[text() = 'Bob'] |
|
745 |
|
746 The following will return all authors containing a first-name child whose |
|
747 text is 'Bob': |
|
748 |
|
749 author[first-name!text() = 'Bob'] |
|
750 |
|
751 The following will return all authors containing a child named Bob: |
|
752 |
|
753 author[*!text() = 'Bob'] |
|
754 |
|
755 Method names are case sensitive. |
|
756 See the L<XML::XQL> man page on how to define your own methods and functions. |
|
757 |
|
758 =head2 Information methods |
|
759 |
|
760 The following methods provide information about nodes in a collection. |
|
761 These methods return strings or numbers, |
|
762 and may be used in conjunction with comparison operators within subqueries. |
|
763 |
|
764 =over 4 |
|
765 |
|
766 =item Method: text() |
|
767 |
|
768 The text() method concatenates text of the descendents of a node, |
|
769 normalizing white space along the way. White space will be preserved for a node |
|
770 if the node has the xml:space attribute set to 'preserve', or if the |
|
771 nearest ancestor with the xml:space attribute has the attribute set to |
|
772 'preserve'. When white space is normalized, it is normalized across the |
|
773 entire string. Spaces are used to separate the text between nodes. |
|
774 When entity references are used in a document, spacing is not inserted |
|
775 around the entity refs when they are expanded. |
|
776 |
|
777 In this implementation, the method may receive an optional parameter |
|
778 to indicate whether the text() of Element nodes should include the text() of |
|
779 its Element descendants. See L<XML::XQL> man page for details. |
|
780 |
|
781 Examples: |
|
782 |
|
783 Find the authors whose last name is 'Bob': |
|
784 |
|
785 author[last-name!text() = 'Bob'] |
|
786 |
|
787 Note this is equivalent to: |
|
788 |
|
789 author[last-name = 'Bob'] |
|
790 |
|
791 Find the authors with value 'Matthew Bob': |
|
792 |
|
793 author[text() = 'Matthew Bob'] |
|
794 |
|
795 author[. = 'Matthew Bob'] |
|
796 |
|
797 author = 'Matthew Bob' |
|
798 |
|
799 =item Method: rawText() |
|
800 |
|
801 The rawText() method is similar to the text() method, but it does not |
|
802 normalize whitespace. |
|
803 |
|
804 In this implementation, the method may receive an optional parameter |
|
805 to indicate whether the rawText() of Element nodes should include the |
|
806 rawText() of its Element descendants. See L<XML::XQL> man page for details. |
|
807 |
|
808 =item Method: value() |
|
809 |
|
810 Returns a type cast version of the value of a node. If no data type is |
|
811 provided, returns the same as text(). |
|
812 |
|
813 =over 4 |
|
814 |
|
815 =item Shortcuts |
|
816 |
|
817 For the purposes of comparison, value( )is implied if omitted. |
|
818 In other words, when two items are compared, the comparison is between |
|
819 the value of the two items. Remember that in absence of type information, |
|
820 value() returns text(). |
|
821 |
|
822 The following examples are equivalent: |
|
823 |
|
824 author[last-name!value() = 'Bob' $and$ first-name!value() = 'Joe'] |
|
825 |
|
826 author[last-name = 'Bob' $and$ first-name = 'Joe'] |
|
827 |
|
828 price[@intl!value() = 'canada'] |
|
829 |
|
830 price[@intl = 'canada'] |
|
831 |
|
832 =back |
|
833 |
|
834 =item Method: nodeType() |
|
835 |
|
836 Returns a number to indicate the type of the node. The values were based |
|
837 on the node type values in the DOM: |
|
838 |
|
839 element 1 |
|
840 attribute 2 |
|
841 text 3 |
|
842 entity 6 (not in XQL spec) |
|
843 PI 7 |
|
844 comment 8 |
|
845 document 9 |
|
846 doc. fragment 10 (not in XQL spec) |
|
847 notation 11 (not in XQL spec) |
|
848 |
|
849 Note that in XQL, CDATASection nodes and EntityReference nodes also return 3, |
|
850 whereas in the DOM CDATASection returns 4 and EntityReference returns 5. |
|
851 Use the XQL+ method DOM_nodeType() to get DOM node type values. |
|
852 See the L<XML::DOM> man page for node type values of nodes not mentioned here. |
|
853 |
|
854 =item Method: nodeTypeString |
|
855 |
|
856 Returns the name of the node type in lowercase or an empty string. The |
|
857 following node types are currently supported 1 (element), 2 (attribute), |
|
858 3 (text), 7 (processing_instruction), 8 (comment), 9 (document) |
|
859 |
|
860 =item Method: nodeName() |
|
861 |
|
862 Returns the tag name for Element nodes and the attribute name of attributes. |
|
863 |
|
864 =back |
|
865 |
|
866 =head2 Collection index methods |
|
867 |
|
868 =over 4 |
|
869 |
|
870 =item Method: index() |
|
871 |
|
872 Returns the index of the value within the search context (i.e. with the input |
|
873 list of the subquery.) This is not necessarily the same as the index of a |
|
874 node within its parent node. Note that the XQL spec doesn't explain it well. |
|
875 |
|
876 =over 4 |
|
877 |
|
878 =item Examples: |
|
879 |
|
880 Find the first 3 degrees: |
|
881 |
|
882 degree[index() $lt$ 3] |
|
883 |
|
884 Note that it skips over other nodes that may exist between the degree elements. |
|
885 |
|
886 Consider the following data: |
|
887 |
|
888 <x> |
|
889 <y/> |
|
890 <y/> |
|
891 </x> |
|
892 <x> |
|
893 <y/> |
|
894 <y/> |
|
895 </x> |
|
896 |
|
897 The following expression will return the first y from each x: |
|
898 |
|
899 x/y[index() = 0] |
|
900 |
|
901 This could also be accomplished by (see Indexing into a Collection): |
|
902 |
|
903 x/y[0] |
|
904 |
|
905 =back |
|
906 |
|
907 =item Method: end() |
|
908 |
|
909 The end() method returns true for the last element in the search context. |
|
910 Again, the XQL spec does not explain it well. |
|
911 |
|
912 =over 4 |
|
913 |
|
914 =item Examples: |
|
915 |
|
916 Find the last book: |
|
917 |
|
918 book[end()] |
|
919 |
|
920 Find the last author for each book: |
|
921 |
|
922 book/author[end()] |
|
923 |
|
924 Find the last author from the entire set of authors of books: |
|
925 |
|
926 (book/author)[end()] |
|
927 |
|
928 =back |
|
929 |
|
930 =back |
|
931 |
|
932 =head2 Aggregate methods |
|
933 |
|
934 =over 4 |
|
935 |
|
936 =item Method: count( [QUERY] ) |
|
937 |
|
938 Returns the number of values inside the search context. |
|
939 In XQL+, when the optional QUERY parameter is supplied, it returns the number of |
|
940 values returned by the QUERY. |
|
941 |
|
942 =back |
|
943 |
|
944 =head2 Namespace methods |
|
945 |
|
946 The following methods can be applied to a node to return namespace information. |
|
947 |
|
948 =over 4 |
|
949 |
|
950 =item Method: baseName() |
|
951 |
|
952 Returns the local name portion of the node, excluding the prefix. |
|
953 Local names are defined only for element nodes and attribute nodes. |
|
954 The local name of an element node is the local |
|
955 portion of the node's element type name. The local name of an attribute node is |
|
956 the local portion of the node's attribute name. If a local name is not defined |
|
957 for the reference node, the method evaluates to the empty set. |
|
958 |
|
959 =item Method: namespace() |
|
960 |
|
961 Returns the URI for the namespace of the node. |
|
962 Namespace URIs are defined only for element nodes and attribute nodes. |
|
963 The namespace URI of an element node is the namespace URI associated with the |
|
964 node's element type name. The namespace URI of an attribute node is |
|
965 the namespace URI associated with the node's attribute name. If a namespace |
|
966 URI is not defined for the reference node, the method evaluates to the |
|
967 empty set. |
|
968 |
|
969 =item Method: prefix() |
|
970 |
|
971 Returns the prefix for the node. Namespace prefixes are defined only for |
|
972 element nodes and attribute nodes. The namespace prefix of an element |
|
973 node is the shortname for the namespace of the node's element type name. |
|
974 The namespace prefix of an attribute |
|
975 node is the shortname for the namespace of the node's attribute name. |
|
976 If a namespace prefix is not defined |
|
977 for the reference node, the method evaluates to the empty set. |
|
978 |
|
979 The spec states: A node's namespace prefix may be defined |
|
980 within the query expression, within the document under query, or within both |
|
981 the query expression and the document under query. If it is defined in both |
|
982 places the prefixes may not agree. In this case, the prefix assigned by |
|
983 the query expression takes precedence. |
|
984 In this implementation you cannot define the namespace for a query, so this |
|
985 can never happen. |
|
986 |
|
987 =over 4 |
|
988 |
|
989 =item Examples: |
|
990 |
|
991 Find all unqualified book elements. Note that this does not return my:book |
|
992 elements: |
|
993 |
|
994 book |
|
995 |
|
996 Find all book elements with the prefix 'my'. Note that this query does not |
|
997 return unqualified book elements: |
|
998 |
|
999 my:book |
|
1000 |
|
1001 Find all book elements with a 'my' prefix that have an author subelement: |
|
1002 |
|
1003 my:book[author] |
|
1004 |
|
1005 Find all book elements with a 'my' prefix that have an author subelement with a |
|
1006 my prefix: |
|
1007 |
|
1008 my:book[my:author] |
|
1009 |
|
1010 Find all elements with a prefix of 'my': |
|
1011 |
|
1012 my:* |
|
1013 |
|
1014 Find all book elements from any namespace: |
|
1015 |
|
1016 *:book |
|
1017 |
|
1018 Find any element from any namespace: |
|
1019 |
|
1020 * |
|
1021 |
|
1022 Find the style attribute with a 'my' prefix within a book element: |
|
1023 |
|
1024 book/@my:style |
|
1025 |
|
1026 =back |
|
1027 |
|
1028 All attributes of an element can be returned using @*. |
|
1029 This is potentially useful for applications that treat attributes |
|
1030 as fields in a record. |
|
1031 |
|
1032 =over 4 |
|
1033 |
|
1034 =item Examples: |
|
1035 |
|
1036 Find all attributes of the current element context: |
|
1037 |
|
1038 @* |
|
1039 |
|
1040 Find style attributes from any namespace: |
|
1041 |
|
1042 @*:style |
|
1043 |
|
1044 Find all attributes from the 'my' namespace, including unqualified attributes on |
|
1045 elements from the 'my' namespace: |
|
1046 |
|
1047 @my:* |
|
1048 |
|
1049 =back |
|
1050 |
|
1051 =back |
|
1052 |
|
1053 =head1 Functions |
|
1054 |
|
1055 This section defines the functions of XQL. The spec states that: |
|
1056 XQL defines two kinds of functions: |
|
1057 collection functions and pure functions. Collection functions use the search |
|
1058 context of the Invocation instance, while pure functions ignore the |
|
1059 search context, except to evaluate the function's parameters. A collection |
|
1060 function evaluates to a subset of the search context, and a pure function |
|
1061 evaluates to either a constant value or to a value that depends only on the |
|
1062 function's parameters. |
|
1063 |
|
1064 Don't worry if you don't get it. Just use them! |
|
1065 |
|
1066 =head2 Collection functions |
|
1067 |
|
1068 The collection functions provide access to the various types of nodes in a |
|
1069 document. Any of these collections can be constrained and indexed. |
|
1070 The collections return the set of children of the reference node meeting the |
|
1071 particular restriction. |
|
1072 |
|
1073 =over 4 |
|
1074 |
|
1075 =item Function: textNode() |
|
1076 |
|
1077 The collection of text nodes. |
|
1078 |
|
1079 =item Function: comment() |
|
1080 |
|
1081 The collection of comment nodes. |
|
1082 |
|
1083 =item Function: pi() |
|
1084 |
|
1085 The collection of processing instruction nodes. |
|
1086 |
|
1087 =item Function: element( [NAME] ) |
|
1088 |
|
1089 The collection of all element nodes. If the optional text |
|
1090 parameter is provided, it only returns element children |
|
1091 matching that particular name. |
|
1092 |
|
1093 =item Function: attribute( [NAME] ) |
|
1094 |
|
1095 The collection of all attribute nodes. If the optional text |
|
1096 parameter is provided, it only returns attributes matching that |
|
1097 particular name. |
|
1098 |
|
1099 =item Function: node() |
|
1100 |
|
1101 The collection of all non-attribute nodes. |
|
1102 |
|
1103 =over 4 |
|
1104 |
|
1105 =item Examples: |
|
1106 |
|
1107 Find the second text node in each p element in the current context: |
|
1108 |
|
1109 p/textNode()[1] |
|
1110 |
|
1111 Find the second comment anywhere in the document. See Context for details on |
|
1112 setting the context to the document root: |
|
1113 |
|
1114 //comment()[1] |
|
1115 |
|
1116 =back |
|
1117 |
|
1118 =back |
|
1119 |
|
1120 =head2 Other XQL Functions |
|
1121 |
|
1122 =over 4 |
|
1123 |
|
1124 =item Function: ancestor(QUERY) |
|
1125 |
|
1126 Finds the nearest ancestor matching the provided query. It returns either a |
|
1127 single element result or an empty set []. |
|
1128 Note that this node is never the reference node itself. |
|
1129 |
|
1130 =over 4 |
|
1131 |
|
1132 =item Examples: |
|
1133 |
|
1134 Find the nearest book ancestor of the current element: |
|
1135 |
|
1136 ancestor(book) |
|
1137 |
|
1138 Find the nearest ancestor author element that is contained in a book element: |
|
1139 |
|
1140 ancestor(book/author) |
|
1141 |
|
1142 =back |
|
1143 |
|
1144 =item Function: id(NAME) |
|
1145 |
|
1146 Pure function that evaluates to a set. The set contains an element node that |
|
1147 has an 'id' attribute whose value is identical to the string that the Text |
|
1148 parameter quotes. The element node may appear anywhere within the |
|
1149 document under query. If more than one element node meets these criteria, |
|
1150 the function evaluates to a set that contains the first node appearing in a |
|
1151 document ordering of the nodes. |
|
1152 |
|
1153 =item Function: true() and false() |
|
1154 |
|
1155 Pure functions that each evaluate to a Boolean. "true()" evaluates to 'true', |
|
1156 and "false()" evaluates to 'false'. These functions are useful in expressions |
|
1157 that are constructed using entity references or variable substitution, since |
|
1158 they may replace an expression found in an instance of Subquery without |
|
1159 violating the syntax required by the instance of Subquery. |
|
1160 They return an object of type XML::XQL::Boolean. |
|
1161 |
|
1162 =item Function: date(QUERY) |
|
1163 |
|
1164 "date" is a pure function that typecasts the value of its parameter to a set of |
|
1165 dates. If the parameter matches a single string, the value of the function is a |
|
1166 set containing a single date. If the parameter matches a QUERY, the value of |
|
1167 the function is a set of dates, where the set contains one date for each member |
|
1168 of the set to which the parameter evaluates. |
|
1169 |
|
1170 XQL does not define the representation of the date value, nor does it |
|
1171 define how the function translates parameter values into dates. |
|
1172 This implementation uses the Date::Manip module to parse dates, which accepts |
|
1173 almost any imaginable format. See L<XML::XQL> to plug in your own |
|
1174 Date implementation. |
|
1175 |
|
1176 Include the L<XML::XQL::Date> package to add the XQL date type and the date() |
|
1177 function, like this: |
|
1178 |
|
1179 use XML::XQL::Date; |
|
1180 |
|
1181 =item Perl builtin functions and other XQL+ functions |
|
1182 |
|
1183 XQL+ provides XQL function wrappers for most Perl builtin functions. |
|
1184 It also provides other cool functions like subst(), map(), and eval() that |
|
1185 allow you to modify documents and embed perl code. |
|
1186 If this is still not enough, you can add your own function and methods. |
|
1187 See L<XML::XQL> man page for details. |
|
1188 |
|
1189 =back |
|
1190 |
|
1191 =head1 Sequence Operators - ';' and ';;' |
|
1192 |
|
1193 The whitepaper 'The Design of XQL' by Jonathan Robie, which can be found |
|
1194 at L<http://www.texcel.no/whitepapers/xql-design.html> describes the sequence |
|
1195 operators ';;' (precedes) and ';' (immediately precedes.) Although these |
|
1196 operators are not included in the XQL spec, I thought I'd add them anyway. |
|
1197 |
|
1198 =head2 Immediately Precedes - ';' |
|
1199 |
|
1200 =over 4 |
|
1201 |
|
1202 =item Example: |
|
1203 |
|
1204 With the following input: |
|
1205 |
|
1206 <TABLE> |
|
1207 <ROWS> |
|
1208 <TR> |
|
1209 <TD>Shady Grove</TD> |
|
1210 <TD>Aeolian</TD> |
|
1211 </TR> |
|
1212 <TR> |
|
1213 <TD>Over the River, Charlie</TD> |
|
1214 <TD>Dorian</TD> |
|
1215 </TR> |
|
1216 </ROWS> |
|
1217 </TABLE> |
|
1218 |
|
1219 Find the TD node that contains "Shady Grove" and the TD node that immediately |
|
1220 follows it: |
|
1221 |
|
1222 //(TD="Shady Grove" ; TD) |
|
1223 |
|
1224 =back |
|
1225 |
|
1226 Note that in XML::DOM there is actually a text node with whitespace between |
|
1227 the two TD nodes, but those are ignored by this operator, unless the text node |
|
1228 has 'xml:space' set to 'preserve'. See ??? for details. |
|
1229 |
|
1230 =head2 Precedes - ';;' |
|
1231 |
|
1232 =over 4 |
|
1233 |
|
1234 =item Example: |
|
1235 |
|
1236 With the following input (from Hamlet): |
|
1237 |
|
1238 <SPEECH> |
|
1239 <SPEAKER>MARCELLUS</SPEAKER> |
|
1240 <LINE>Tis gone!</LINE> |
|
1241 <STAGEDIR>Exit Ghost</STAGEDIR> |
|
1242 <LINE>We do it wrong, being so majestical,</LINE> |
|
1243 <LINE>To offer it the show of violence;</LINE> |
|
1244 <LINE>For it is, as the air, invulnerable,</LINE> |
|
1245 <LINE>And our vain blows malicious mockery.</LINE> |
|
1246 </SPEECH> |
|
1247 |
|
1248 Return the STAGEDIR and all the LINEs that follow it: |
|
1249 |
|
1250 SPEECH//( STAGEDIR ;; LINE ) |
|
1251 |
|
1252 Suppose an actor playing the ghost wants to know when to exit; that is, he |
|
1253 wants to know who says what line just before |
|
1254 he is supposed to exit. The line immediately precedes the stagedir, but the |
|
1255 speaker may occur at any time before the line. |
|
1256 In this query, we will use the "precedes" operator (";;") to identify a speaker |
|
1257 that precedes the line somewhere within a |
|
1258 speech. Our ghost can find the required information with the following query, |
|
1259 which selects the speaker, the line, and the stagedir: |
|
1260 |
|
1261 SPEECH//( SPEAKER ;; LINE ; STAGEDIR="Exit Ghost") |
|
1262 |
|
1263 =back |
|
1264 |
|
1265 =head1 Operator Precedence |
|
1266 |
|
1267 The following table lists operators in precedence order, highest precedence |
|
1268 first, where operators of a given row have the same precedence. |
|
1269 The table also lists the associated productions: |
|
1270 |
|
1271 Production Operator(s) |
|
1272 ---------- ----------- |
|
1273 Grouping ( ) |
|
1274 Filter [ ] |
|
1275 Subscript [ ] |
|
1276 Bang ! |
|
1277 Path / // |
|
1278 Match $match$ $no_match$ =~ !~ (XQL+ only) |
|
1279 Comparison = != < <= > >= $eq$ $ne$ $lt$ $le$ $gt$ |
|
1280 $ge$ $ieq$ $ine$ $ilt$ $ile$ $igt$ $ige$ |
|
1281 Intersection $intersect$ |
|
1282 Union $union$ | |
|
1283 Negation $not$ |
|
1284 Conjunction $and$ |
|
1285 Disjunction $or$ |
|
1286 Sequence ; ;; |
|
1287 |
|
1288 =head1 Sample XML Document - bookstore.xml |
|
1289 |
|
1290 This file is also stored in samples/bookstore.xml that comes with the |
|
1291 XML::XQL distribution. |
|
1292 |
|
1293 <?xml version='1.0'?> |
|
1294 <!-- This file represents a fragment of a book store inventory database --> |
|
1295 <bookstore specialty='novel'> |
|
1296 <book style='autobiography'> |
|
1297 <title>Seven Years in Trenton</title> |
|
1298 <author> |
|
1299 <first-name>Joe</first-name> |
|
1300 <last-name>Bob</last-name> |
|
1301 <award>Trenton Literary Review Honorable Mention</award> |
|
1302 </author> |
|
1303 <price>12</price> |
|
1304 </book> |
|
1305 <book style='textbook'> |
|
1306 <title>History of Trenton</title> |
|
1307 <author> |
|
1308 <first-name>Mary</first-name> |
|
1309 <last-name>Bob</last-name> |
|
1310 <publication> |
|
1311 Selected Short Stories of |
|
1312 <first-name>Mary</first-name> <last-name>Bob</last-name> |
|
1313 </publication> |
|
1314 </author> |
|
1315 <price>55</price> |
|
1316 </book> |
|
1317 <magazine style='glossy' frequency='monthly'> |
|
1318 <title>Tracking Trenton</title> |
|
1319 <price>2.50</price> |
|
1320 <subscription price='24' per='year'/> |
|
1321 </magazine> |
|
1322 <book style='novel' id='myfave'> |
|
1323 <title>Trenton Today, Trenton Tomorrow</title> |
|
1324 <author> |
|
1325 <first-name>Toni</first-name> |
|
1326 <last-name>Bob</last-name> |
|
1327 <degree from='Trenton U'>B.A.</degree> |
|
1328 <degree from='Harvard'>Ph.D.</degree> |
|
1329 <award>Pulizer</award> |
|
1330 <publication>Still in Trenton</publication> |
|
1331 <publication>Trenton Forever</publication> |
|
1332 </author> |
|
1333 <price intl='canada' exchange='0.7'>6.50</price> |
|
1334 <excerpt> |
|
1335 <p>It was a dark and stormy night.</p> |
|
1336 <p>But then all nights in Trenton seem dark and |
|
1337 stormy to someone who has gone through what |
|
1338 <emph>I</emph> have.</p> |
|
1339 <definition-list> |
|
1340 <term>Trenton</term> |
|
1341 <definition>misery</definition> |
|
1342 </definition-list> |
|
1343 </excerpt> |
|
1344 </book> |
|
1345 <my:book style='leather' price='29.50' xmlns:my='http://www.placeholder-name-here.com/schema/'> |
|
1346 <my:title>Who's Who in Trenton</my:title> |
|
1347 <my:author>Robert Bob</my:author> |
|
1348 </my:book> |
|
1349 </bookstore> |
|
1350 |
|
1351 =head1 SEE ALSO |
|
1352 |
|
1353 The Japanese version of this document can be found on-line at |
|
1354 L<http://member.nifty.ne.jp/hippo2000/perltips/xml/xql/tutorial.htm> |
|
1355 |
|
1356 L<XML::XQL>, L<XML::XQL::Date>, L<XML::XQL::Query> and L<XML::XQL::DOM> |
|
1357 |
|