1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
|
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>XPath</title>
<link rel="stylesheet" href="../pugixml.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
<link rel="home" href="../manual.html" title="pugixml 1.6">
<link rel="up" href="../manual.html" title="pugixml 1.6">
<link rel="prev" href="saving.html" title="Saving document">
<link rel="next" href="changes.html" title="Changelog">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table width="100%"><tr>
<td>
<a href="http://pugixml.org/">pugixml 1.6</a> manual |
<a href="../manual.html">Overview</a> |
<a href="install.html">Installation</a> |
Document:
<a href="dom.html">Object model</a> · <a href="loading.html">Loading</a> · <a href="access.html">Accessing</a> · <a href="modify.html">Modifying</a> · <a href="saving.html">Saving</a> |
<b>XPath</b> |
<a href="apiref.html">API Reference</a> |
<a href="toc.html">Table of Contents</a>
</td>
<td width="*" align="right"><div class="spirit-nav">
<a accesskey="p" href="saving.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../manual.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../manual.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="changes.html"><img src="../images/next.png" alt="Next"></a>
</div></td>
</tr></table>
<hr>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="manual.xpath"></a><a class="link" href="xpath.html" title="XPath"> XPath</a>
</h2></div></div></div>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="xpath.html#manual.xpath.types"> XPath types</a></span></dt>
<dt><span class="section"><a href="xpath.html#manual.xpath.select"> Selecting nodes via XPath expression</a></span></dt>
<dt><span class="section"><a href="xpath.html#manual.xpath.query"> Using query objects</a></span></dt>
<dt><span class="section"><a href="xpath.html#manual.xpath.variables"> Using variables</a></span></dt>
<dt><span class="section"><a href="xpath.html#manual.xpath.errors"> Error handling</a></span></dt>
<dt><span class="section"><a href="xpath.html#manual.xpath.w3c"> Conformance to W3C specification</a></span></dt>
</dl></div>
<p>
If the task at hand is to select a subset of document nodes that match some
criteria, it is possible to code a function using the existing traversal functionality
for any practical criteria. However, often either a data-driven approach is
desirable, in case the criteria are not predefined and come from a file, or
it is inconvenient to use traversal interfaces and a higher-level DSL is required.
There is a standard language for XML processing, XPath, that can be useful
for these cases. pugixml implements an almost complete subset of XPath 1.0.
Because of differences in document object model and some performance implications,
there are minor violations of the official specifications, which can be found
in <a class="xref" href="xpath.html#manual.xpath.w3c" title="Conformance to W3C specification"> Conformance to W3C specification</a>. The rest of this section describes the interface for XPath
functionality. Please note that if you wish to learn to use XPath language,
you have to look for other tutorials or manuals; for example, you can read
<a href="http://www.w3schools.com/xpath/" target="_top">W3Schools XPath tutorial</a>,
<a href="http://www.tizag.com/xmlTutorial/xpathtutorial.php" target="_top">XPath tutorial
at tizag.com</a>, and <a href="http://www.w3.org/TR/xpath/" target="_top">the XPath
1.0 specification</a>.
</p>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="manual.xpath.types"></a><a class="link" href="xpath.html#manual.xpath.types" title="XPath types"> XPath types</a>
</h3></div></div></div>
<a name="xpath_value_type"></a><a name="xpath_type_number"></a><a name="xpath_type_string"></a><a name="xpath_type_boolean"></a><a name="xpath_type_node_set"></a><a name="xpath_type_none"></a><p>
Each XPath expression can have one of the following types: boolean, number,
string or node set. Boolean type corresponds to <code class="computeroutput"><span class="keyword">bool</span></code>
type, number type corresponds to <code class="computeroutput"><span class="keyword">double</span></code>
type, string type corresponds to either <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>
or <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">wstring</span></code>, depending on whether <a class="link" href="dom.html#manual.dom.unicode" title="Unicode interface">wide
character interface is enabled</a>, and node set corresponds to <a class="link" href="xpath.html#xpath_node_set">xpath_node_set</a> type. There is an enumeration,
<code class="computeroutput"><span class="identifier">xpath_value_type</span></code>, which can
take the values <code class="computeroutput"><span class="identifier">xpath_type_boolean</span></code>,
<code class="computeroutput"><span class="identifier">xpath_type_number</span></code>, <code class="computeroutput"><span class="identifier">xpath_type_string</span></code> or <code class="computeroutput"><span class="identifier">xpath_type_node_set</span></code>,
accordingly.
</p>
<a name="xpath_node"></a><a name="xpath_node::node"></a><a name="xpath_node::attribute"></a><a name="xpath_node::parent"></a><p>
Because an XPath node can be either a node or an attribute, there is a special
type, <code class="computeroutput"><span class="identifier">xpath_node</span></code>, which is
a discriminated union of these types. A value of this type contains two node
handles, one of <code class="computeroutput"><span class="identifier">xml_node</span></code>
type, and another one of <code class="computeroutput"><span class="identifier">xml_attribute</span></code>
type; at most one of them can be non-null. The accessors to get these handles
are available:
</p>
<pre class="programlisting"><span class="identifier">xml_node</span> <span class="identifier">xpath_node</span><span class="special">::</span><span class="identifier">node</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
<span class="identifier">xml_attribute</span> <span class="identifier">xpath_node</span><span class="special">::</span><span class="identifier">attribute</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
</pre>
<p>
XPath nodes can be null, in which case both accessors return null handles.
</p>
<p>
Note that as per XPath specification, each XPath node has a parent, which
can be retrieved via this function:
</p>
<pre class="programlisting"><span class="identifier">xml_node</span> <span class="identifier">xpath_node</span><span class="special">::</span><span class="identifier">parent</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
</pre>
<p>
<code class="computeroutput"><span class="identifier">parent</span></code> function returns the
node's parent if the XPath node corresponds to <code class="computeroutput"><span class="identifier">xml_node</span></code>
handle (equivalent to <code class="computeroutput"><span class="identifier">node</span><span class="special">().</span><span class="identifier">parent</span><span class="special">()</span></code>), or the node to which the attribute belongs
to, if the XPath node corresponds to <code class="computeroutput"><span class="identifier">xml_attribute</span></code>
handle. For null nodes, <code class="computeroutput"><span class="identifier">parent</span></code>
returns null handle.
</p>
<a name="xpath_node::unspecified_bool_type"></a><a name="xpath_node::comparison"></a><p>
Like node and attribute handles, XPath node handles can be implicitly cast
to boolean-like object to check if it is a null node, and also can be compared
for equality with each other.
</p>
<a name="xpath_node::ctor"></a><p>
You can also create XPath nodes with one of the three constructors: the default
constructor, the constructor that takes node argument, and the constructor
that takes attribute and node arguments (in which case the attribute must
belong to the attribute list of the node). The constructor from <code class="computeroutput"><span class="identifier">xml_node</span></code> is implicit, so you can usually
pass <code class="computeroutput"><span class="identifier">xml_node</span></code> to functions
that expect <code class="computeroutput"><span class="identifier">xpath_node</span></code>. Apart
from that you usually don't need to create your own XPath node objects, since
they are returned to you via selection functions.
</p>
<a name="xpath_node_set"></a><p>
XPath expressions operate not on single nodes, but instead on node sets.
A node set is a collection of nodes, which can be optionally ordered in either
a forward document order or a reverse one. Document order is defined in XPath
specification; an XPath node is before another node in document order if
it appears before it in XML representation of the corresponding document.
</p>
<a name="xpath_node_set::const_iterator"></a><a name="xpath_node_set::begin"></a><a name="xpath_node_set::end"></a><p>
Node sets are represented by <code class="computeroutput"><span class="identifier">xpath_node_set</span></code>
object, which has an interface that resembles one of sequential random-access
containers. It has an iterator type along with usual begin/past-the-end iterator
accessors:
</p>
<pre class="programlisting"><span class="keyword">typedef</span> <span class="keyword">const</span> <span class="identifier">xpath_node</span><span class="special">*</span> <span class="identifier">xpath_node_set</span><span class="special">::</span><span class="identifier">const_iterator</span><span class="special">;</span>
<span class="identifier">const_iterator</span> <span class="identifier">xpath_node_set</span><span class="special">::</span><span class="identifier">begin</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
<span class="identifier">const_iterator</span> <span class="identifier">xpath_node_set</span><span class="special">::</span><span class="identifier">end</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
</pre>
<a name="xpath_node_set::index"></a><a name="xpath_node_set::size"></a><a name="xpath_node_set::empty"></a><p>
And it also can be iterated via indices, just like <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span></code>:
</p>
<pre class="programlisting"><span class="keyword">const</span> <span class="identifier">xpath_node</span><span class="special">&</span> <span class="identifier">xpath_node_set</span><span class="special">::</span><span class="keyword">operator</span><span class="special">[](</span><span class="identifier">size_t</span> <span class="identifier">index</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
<span class="identifier">size_t</span> <span class="identifier">xpath_node_set</span><span class="special">::</span><span class="identifier">size</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
<span class="keyword">bool</span> <span class="identifier">xpath_node_set</span><span class="special">::</span><span class="identifier">empty</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
</pre>
<p>
All of the above operations have the same semantics as that of <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span></code>:
the iterators are random-access, all of the above operations are constant
time, and accessing the element at index that is greater or equal than the
set size results in undefined behavior. You can use both iterator-based and
index-based access for iteration, however the iterator-based one can be faster.
</p>
<a name="xpath_node_set::type"></a><a name="xpath_node_set::type_unsorted"></a><a name="xpath_node_set::type_sorted"></a><a name="xpath_node_set::type_sorted_reverse"></a><a name="xpath_node_set::sort"></a><p>
The order of iteration depends on the order of nodes inside the set; the
order can be queried via the following function:
</p>
<pre class="programlisting"><span class="keyword">enum</span> <span class="identifier">xpath_node_set</span><span class="special">::</span><span class="identifier">type_t</span> <span class="special">{</span><span class="identifier">type_unsorted</span><span class="special">,</span> <span class="identifier">type_sorted</span><span class="special">,</span> <span class="identifier">type_sorted_reverse</span><span class="special">};</span>
<span class="identifier">type_t</span> <span class="identifier">xpath_node_set</span><span class="special">::</span><span class="identifier">type</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
</pre>
<p>
<code class="computeroutput"><span class="identifier">type</span></code> function returns the
current order of nodes; <code class="computeroutput"><span class="identifier">type_sorted</span></code>
means that the nodes are in forward document order, <code class="computeroutput"><span class="identifier">type_sorted_reverse</span></code>
means that the nodes are in reverse document order, and <code class="computeroutput"><span class="identifier">type_unsorted</span></code>
means that neither order is guaranteed (nodes can accidentally be in a sorted
order even if <code class="computeroutput"><span class="identifier">type</span><span class="special">()</span></code>
returns <code class="computeroutput"><span class="identifier">type_unsorted</span></code>). If
you require a specific order of iteration, you can change it via <code class="computeroutput"><span class="identifier">sort</span></code> function:
</p>
<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">xpath_node_set</span><span class="special">::</span><span class="identifier">sort</span><span class="special">(</span><span class="keyword">bool</span> <span class="identifier">reverse</span> <span class="special">=</span> <span class="keyword">false</span><span class="special">);</span>
</pre>
<p>
Calling <code class="computeroutput"><span class="identifier">sort</span></code> sorts the nodes
in either forward or reverse document order, depending on the argument; after
this call <code class="computeroutput"><span class="identifier">type</span><span class="special">()</span></code>
will return <code class="computeroutput"><span class="identifier">type_sorted</span></code> or
<code class="computeroutput"><span class="identifier">type_sorted_reverse</span></code>.
</p>
<a name="xpath_node_set::first"></a><p>
Often the actual iteration is not needed; instead, only the first element
in document order is required. For this, a special accessor is provided:
</p>
<pre class="programlisting"><span class="identifier">xpath_node</span> <span class="identifier">xpath_node_set</span><span class="special">::</span><span class="identifier">first</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
</pre>
<p>
This function returns the first node in forward document order from the set,
or null node if the set is empty. Note that while the result of the node
does not depend on the order of nodes in the set (i.e. on the result of
<code class="computeroutput"><span class="identifier">type</span><span class="special">()</span></code>),
the complexity does - if the set is sorted, the complexity is constant, otherwise
it is linear in the number of elements or worse.
</p>
<a name="xpath_node_set::ctor"></a><p>
While in the majority of cases the node set is returned by XPath functions,
sometimes there is a need to manually construct a node set. For such cases,
a constructor is provided which takes an iterator range (<code class="computeroutput"><span class="identifier">const_iterator</span></code>
is a typedef for <code class="computeroutput"><span class="keyword">const</span> <span class="identifier">xpath_node</span><span class="special">*</span></code>), and an optional type:
</p>
<pre class="programlisting"><span class="identifier">xpath_node_set</span><span class="special">::</span><span class="identifier">xpath_node_set</span><span class="special">(</span><span class="identifier">const_iterator</span> <span class="identifier">begin</span><span class="special">,</span> <span class="identifier">const_iterator</span> <span class="identifier">end</span><span class="special">,</span> <span class="identifier">type_t</span> <span class="identifier">type</span> <span class="special">=</span> <span class="identifier">type_unsorted</span><span class="special">);</span>
</pre>
<p>
The constructor copies the specified range and sets the specified type. The
objects in the range are not checked in any way; you'll have to ensure that
the range contains no duplicates, and that the objects are sorted according
to the <code class="computeroutput"><span class="identifier">type</span></code> parameter. Otherwise
XPath operations with this set may produce unexpected results.
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="manual.xpath.select"></a><a class="link" href="xpath.html#manual.xpath.select" title="Selecting nodes via XPath expression"> Selecting nodes via XPath expression</a>
</h3></div></div></div>
<a name="xml_node::select_node"></a><a name="xml_node::select_nodes"></a><p>
If you want to select nodes that match some XPath expression, you can do
it with the following functions:
</p>
<pre class="programlisting"><span class="identifier">xpath_node</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">select_node</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">query</span><span class="special">,</span> <span class="identifier">xpath_variable_set</span><span class="special">*</span> <span class="identifier">variables</span> <span class="special">=</span> <span class="number">0</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
<span class="identifier">xpath_node_set</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">select_nodes</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">query</span><span class="special">,</span> <span class="identifier">xpath_variable_set</span><span class="special">*</span> <span class="identifier">variables</span> <span class="special">=</span> <span class="number">0</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
</pre>
<p>
<code class="computeroutput"><span class="identifier">select_nodes</span></code> function compiles
the expression and then executes it with the node as a context node, and
returns the resulting node set. <code class="computeroutput"><span class="identifier">select_node</span></code>
returns only the first node in document order from the result, and is equivalent
to calling <code class="computeroutput"><span class="identifier">select_nodes</span><span class="special">(</span><span class="identifier">query</span><span class="special">).</span><span class="identifier">first</span><span class="special">()</span></code>.
If the XPath expression does not match anything, or the node handle is null,
<code class="computeroutput"><span class="identifier">select_nodes</span></code> returns an empty
set, and <code class="computeroutput"><span class="identifier">select_node</span></code> returns
null XPath node.
</p>
<p>
If exception handling is not disabled, both functions throw <a class="link" href="xpath.html#xpath_exception">xpath_exception</a>
if the query can not be compiled or if it returns a value with type other
than node set; see <a class="xref" href="xpath.html#manual.xpath.errors" title="Error handling"> Error handling</a> for details.
</p>
<a name="xml_node::select_node_precomp"></a><a name="xml_node::select_nodes_precomp"></a><p>
While compiling expressions is fast, the compilation time can introduce a
significant overhead if the same expression is used many times on small subtrees.
If you're doing many similar queries, consider compiling them into query
objects (see <a class="xref" href="xpath.html#manual.xpath.query" title="Using query objects"> Using query objects</a> for further reference). Once you get a compiled
query object, you can pass it to select functions instead of an expression
string:
</p>
<pre class="programlisting"><span class="identifier">xpath_node</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">select_node</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">xpath_query</span><span class="special">&</span> <span class="identifier">query</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
<span class="identifier">xpath_node_set</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">select_nodes</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">xpath_query</span><span class="special">&</span> <span class="identifier">query</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
</pre>
<p>
If exception handling is not disabled, both functions throw <a class="link" href="xpath.html#xpath_exception">xpath_exception</a>
if the query returns a value with type other than node set.
</p>
<p>
This is an example of selecting nodes using XPath expressions (<a href="../samples/xpath_select.cpp" target="_top">samples/xpath_select.cpp</a>):
</p>
<p>
</p>
<pre class="programlisting"><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xpath_node_set</span> <span class="identifier">tools</span> <span class="special">=</span> <span class="identifier">doc</span><span class="special">.</span><span class="identifier">select_nodes</span><span class="special">(</span><span class="string">"/Profile/Tools/Tool[@AllowRemote='true' and @DeriveCaptionFrom='lastparam']"</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"Tools:\n"</span><span class="special">;</span>
<span class="keyword">for</span> <span class="special">(</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xpath_node_set</span><span class="special">::</span><span class="identifier">const_iterator</span> <span class="identifier">it</span> <span class="special">=</span> <span class="identifier">tools</span><span class="special">.</span><span class="identifier">begin</span><span class="special">();</span> <span class="identifier">it</span> <span class="special">!=</span> <span class="identifier">tools</span><span class="special">.</span><span class="identifier">end</span><span class="special">();</span> <span class="special">++</span><span class="identifier">it</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xpath_node</span> <span class="identifier">node</span> <span class="special">=</span> <span class="special">*</span><span class="identifier">it</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">node</span><span class="special">.</span><span class="identifier">node</span><span class="special">().</span><span class="identifier">attribute</span><span class="special">(</span><span class="string">"Filename"</span><span class="special">).</span><span class="identifier">value</span><span class="special">()</span> <span class="special"><<</span> <span class="string">"\n"</span><span class="special">;</span>
<span class="special">}</span>
<span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xpath_node</span> <span class="identifier">build_tool</span> <span class="special">=</span> <span class="identifier">doc</span><span class="special">.</span><span class="identifier">select_node</span><span class="special">(</span><span class="string">"//Tool[contains(Description, 'build system')]"</span><span class="special">);</span>
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">build_tool</span><span class="special">)</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"Build tool: "</span> <span class="special"><<</span> <span class="identifier">build_tool</span><span class="special">.</span><span class="identifier">node</span><span class="special">().</span><span class="identifier">attribute</span><span class="special">(</span><span class="string">"Filename"</span><span class="special">).</span><span class="identifier">value</span><span class="special">()</span> <span class="special"><<</span> <span class="string">"\n"</span><span class="special">;</span>
</pre>
<p>
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="manual.xpath.query"></a><a class="link" href="xpath.html#manual.xpath.query" title="Using query objects"> Using query objects</a>
</h3></div></div></div>
<a name="xpath_query"></a><p>
When you call <code class="computeroutput"><span class="identifier">select_nodes</span></code>
with an expression string as an argument, a query object is created behind
the scenes. A query object represents a compiled XPath expression. Query
objects can be needed in the following circumstances:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
You can precompile expressions to query objects to save compilation time
if it becomes an issue;
</li>
<li class="listitem">
You can use query objects to evaluate XPath expressions which result
in booleans, numbers or strings;
</li>
<li class="listitem">
You can get the type of expression value via query object.
</li>
</ul></div>
<p>
Query objects correspond to <code class="computeroutput"><span class="identifier">xpath_query</span></code>
type. They are immutable and non-copyable: they are bound to the expression
at creation time and can not be cloned. If you want to put query objects
in a container, allocate them on heap via <code class="computeroutput"><span class="keyword">new</span></code>
operator and store pointers to <code class="computeroutput"><span class="identifier">xpath_query</span></code>
in the container.
</p>
<a name="xpath_query::ctor"></a><p>
You can create a query object with the constructor that takes XPath expression
as an argument:
</p>
<pre class="programlisting"><span class="keyword">explicit</span> <span class="identifier">xpath_query</span><span class="special">::</span><span class="identifier">xpath_query</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">query</span><span class="special">,</span> <span class="identifier">xpath_variable_set</span><span class="special">*</span> <span class="identifier">variables</span> <span class="special">=</span> <span class="number">0</span><span class="special">);</span>
</pre>
<a name="xpath_query::return_type"></a><p>
The expression is compiled and the compiled representation is stored in the
new query object. If compilation fails, <a class="link" href="xpath.html#xpath_exception">xpath_exception</a>
is thrown if exception handling is not disabled (see <a class="xref" href="xpath.html#manual.xpath.errors" title="Error handling"> Error handling</a> for
details). After the query is created, you can query the type of the evaluation
result using the following function:
</p>
<pre class="programlisting"><span class="identifier">xpath_value_type</span> <span class="identifier">xpath_query</span><span class="special">::</span><span class="identifier">return_type</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
</pre>
<a name="xpath_query::evaluate_boolean"></a><a name="xpath_query::evaluate_number"></a><a name="xpath_query::evaluate_string"></a><a name="xpath_query::evaluate_node_set"></a><a name="xpath_query::evaluate_node"></a><p>
You can evaluate the query using one of the following functions:
</p>
<pre class="programlisting"><span class="keyword">bool</span> <span class="identifier">xpath_query</span><span class="special">::</span><span class="identifier">evaluate_boolean</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">xpath_node</span><span class="special">&</span> <span class="identifier">n</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
<span class="keyword">double</span> <span class="identifier">xpath_query</span><span class="special">::</span><span class="identifier">evaluate_number</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">xpath_node</span><span class="special">&</span> <span class="identifier">n</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
<span class="identifier">string_t</span> <span class="identifier">xpath_query</span><span class="special">::</span><span class="identifier">evaluate_string</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">xpath_node</span><span class="special">&</span> <span class="identifier">n</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
<span class="identifier">xpath_node_set</span> <span class="identifier">xpath_query</span><span class="special">::</span><span class="identifier">evaluate_node_set</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">xpath_node</span><span class="special">&</span> <span class="identifier">n</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
<span class="identifier">xpath_node</span> <span class="identifier">xpath_query</span><span class="special">::</span><span class="identifier">evaluate_node</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">xpath_node</span><span class="special">&</span> <span class="identifier">n</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
</pre>
<p>
All functions take the context node as an argument, compute the expression
and return the result, converted to the requested type. According to XPath
specification, value of any type can be converted to boolean, number or string
value, but no type other than node set can be converted to node set. Because
of this, <code class="computeroutput"><span class="identifier">evaluate_boolean</span></code>,
<code class="computeroutput"><span class="identifier">evaluate_number</span></code> and <code class="computeroutput"><span class="identifier">evaluate_string</span></code> always return a result,
but <code class="computeroutput"><span class="identifier">evaluate_node_set</span></code> and
<code class="computeroutput"><span class="identifier">evaluate_node</span></code> result in an
error if the return type is not node set (see <a class="xref" href="xpath.html#manual.xpath.errors" title="Error handling"> Error handling</a>).
</p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
Calling <code class="computeroutput"><span class="identifier">node</span><span class="special">.</span><span class="identifier">select_nodes</span><span class="special">(</span><span class="string">"query"</span><span class="special">)</span></code>
is equivalent to calling <code class="computeroutput"><span class="identifier">xpath_query</span><span class="special">(</span><span class="string">"query"</span><span class="special">).</span><span class="identifier">evaluate_node_set</span><span class="special">(</span><span class="identifier">node</span><span class="special">)</span></code>. Calling <code class="computeroutput"><span class="identifier">node</span><span class="special">.</span><span class="identifier">select_node</span><span class="special">(</span><span class="string">"query"</span><span class="special">)</span></code> is equivalent to calling <code class="computeroutput"><span class="identifier">xpath_query</span><span class="special">(</span><span class="string">"query"</span><span class="special">).</span><span class="identifier">evaluate_node</span><span class="special">(</span><span class="identifier">node</span><span class="special">)</span></code>.
</p></td></tr>
</table></div>
<a name="xpath_query::evaluate_string_buffer"></a><p>
Note that <code class="computeroutput"><span class="identifier">evaluate_string</span></code>
function returns the STL string; as such, it's not available in <a class="link" href="install.html#PUGIXML_NO_STL">PUGIXML_NO_STL</a>
mode and also usually allocates memory. There is another string evaluation
function:
</p>
<pre class="programlisting"><span class="identifier">size_t</span> <span class="identifier">xpath_query</span><span class="special">::</span><span class="identifier">evaluate_string</span><span class="special">(</span><span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">buffer</span><span class="special">,</span> <span class="identifier">size_t</span> <span class="identifier">capacity</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">xpath_node</span><span class="special">&</span> <span class="identifier">n</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
</pre>
<p>
This function evaluates the string, and then writes the result to <code class="computeroutput"><span class="identifier">buffer</span></code> (but at most <code class="computeroutput"><span class="identifier">capacity</span></code>
characters); then it returns the full size of the result in characters, including
the terminating zero. If <code class="computeroutput"><span class="identifier">capacity</span></code>
is not 0, the resulting buffer is always zero-terminated. You can use this
function as follows:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
First call the function with <code class="computeroutput"><span class="identifier">buffer</span>
<span class="special">=</span> <span class="number">0</span></code>
and <code class="computeroutput"><span class="identifier">capacity</span> <span class="special">=</span>
<span class="number">0</span></code>; then allocate the returned amount
of characters, and call the function again, passing the allocated storage
and the amount of characters;
</li>
<li class="listitem">
First call the function with small buffer and buffer capacity; then,
if the result is larger than the capacity, the output has been trimmed,
so allocate a larger buffer and call the function again.
</li>
</ul></div>
<p>
This is an example of using query objects (<a href="../samples/xpath_query.cpp" target="_top">samples/xpath_query.cpp</a>):
</p>
<p>
</p>
<pre class="programlisting"><span class="comment">// Select nodes via compiled query
</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xpath_query</span> <span class="identifier">query_remote_tools</span><span class="special">(</span><span class="string">"/Profile/Tools/Tool[@AllowRemote='true']"</span><span class="special">);</span>
<span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xpath_node_set</span> <span class="identifier">tools</span> <span class="special">=</span> <span class="identifier">query_remote_tools</span><span class="special">.</span><span class="identifier">evaluate_node_set</span><span class="special">(</span><span class="identifier">doc</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"Remote tool: "</span><span class="special">;</span>
<span class="identifier">tools</span><span class="special">[</span><span class="number">2</span><span class="special">].</span><span class="identifier">node</span><span class="special">().</span><span class="identifier">print</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special">);</span>
<span class="comment">// Evaluate numbers via compiled query
</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xpath_query</span> <span class="identifier">query_timeouts</span><span class="special">(</span><span class="string">"sum(//Tool/@Timeout)"</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">query_timeouts</span><span class="special">.</span><span class="identifier">evaluate_number</span><span class="special">(</span><span class="identifier">doc</span><span class="special">)</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="comment">// Evaluate strings via compiled query for different context nodes
</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xpath_query</span> <span class="identifier">query_name_valid</span><span class="special">(</span><span class="string">"string-length(substring-before(@Filename, '_')) > 0 and @OutputFileMasks"</span><span class="special">);</span>
<span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xpath_query</span> <span class="identifier">query_name</span><span class="special">(</span><span class="string">"concat(substring-before(@Filename, '_'), ' produces ', @OutputFileMasks)"</span><span class="special">);</span>
<span class="keyword">for</span> <span class="special">(</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_node</span> <span class="identifier">tool</span> <span class="special">=</span> <span class="identifier">doc</span><span class="special">.</span><span class="identifier">first_element_by_path</span><span class="special">(</span><span class="string">"Profile/Tools/Tool"</span><span class="special">);</span> <span class="identifier">tool</span><span class="special">;</span> <span class="identifier">tool</span> <span class="special">=</span> <span class="identifier">tool</span><span class="special">.</span><span class="identifier">next_sibling</span><span class="special">())</span>
<span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">s</span> <span class="special">=</span> <span class="identifier">query_name</span><span class="special">.</span><span class="identifier">evaluate_string</span><span class="special">(</span><span class="identifier">tool</span><span class="special">);</span>
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">query_name_valid</span><span class="special">.</span><span class="identifier">evaluate_boolean</span><span class="special">(</span><span class="identifier">tool</span><span class="special">))</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">s</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="special">}</span>
</pre>
<p>
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="manual.xpath.variables"></a><a class="link" href="xpath.html#manual.xpath.variables" title="Using variables"> Using variables</a>
</h3></div></div></div>
<p>
XPath queries may contain references to variables; this is useful if you
want to use queries that depend on some dynamic parameter without manually
preparing the complete query string, or if you want to reuse the same query
object for similar queries.
</p>
<p>
Variable references have the form <code class="computeroutput"><span class="identifier">$name</span></code>; in order to use them, you have to provide
a variable set, which includes all variables present in the query with correct
types. This set is passed to <code class="computeroutput"><span class="identifier">xpath_query</span></code>
constructor or to <code class="computeroutput"><span class="identifier">select_nodes</span></code>/<code class="computeroutput"><span class="identifier">select_node</span></code> functions:
</p>
<pre class="programlisting"><span class="keyword">explicit</span> <span class="identifier">xpath_query</span><span class="special">::</span><span class="identifier">xpath_query</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">query</span><span class="special">,</span> <span class="identifier">xpath_variable_set</span><span class="special">*</span> <span class="identifier">variables</span> <span class="special">=</span> <span class="number">0</span><span class="special">);</span>
<span class="identifier">xpath_node</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">select_node</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">query</span><span class="special">,</span> <span class="identifier">xpath_variable_set</span><span class="special">*</span> <span class="identifier">variables</span> <span class="special">=</span> <span class="number">0</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
<span class="identifier">xpath_node_set</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">select_nodes</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">query</span><span class="special">,</span> <span class="identifier">xpath_variable_set</span><span class="special">*</span> <span class="identifier">variables</span> <span class="special">=</span> <span class="number">0</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
</pre>
<p>
If you're using query objects, you can change the variable values before
<code class="computeroutput"><span class="identifier">evaluate</span></code>/<code class="computeroutput"><span class="identifier">select</span></code>
calls to change the query behavior.
</p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
The variable set pointer is stored in the query object; you have to ensure
that the lifetime of the set exceeds that of query object.
</p></td></tr>
</table></div>
<a name="xpath_variable_set"></a><p>
Variable sets correspond to <code class="computeroutput"><span class="identifier">xpath_variable_set</span></code>
type, which is essentially a variable container.
</p>
<a name="xpath_variable_set::add"></a><p>
You can add new variables with the following function:
</p>
<pre class="programlisting"><span class="identifier">xpath_variable</span><span class="special">*</span> <span class="identifier">xpath_variable_set</span><span class="special">::</span><span class="identifier">add</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">name</span><span class="special">,</span> <span class="identifier">xpath_value_type</span> <span class="identifier">type</span><span class="special">);</span>
</pre>
<p>
The function tries to add a new variable with the specified name and type;
if the variable with such name does not exist in the set, the function adds
a new variable and returns the variable handle; if there is already a variable
with the specified name, the function returns the variable handle if variable
has the specified type. Otherwise the function returns null pointer; it also
returns null pointer on allocation failure.
</p>
<p>
New variables are assigned the default value which depends on the type:
<code class="computeroutput"><span class="number">0</span></code> for numbers, <code class="computeroutput"><span class="keyword">false</span></code> for booleans, empty string for strings
and empty set for node sets.
</p>
<a name="xpath_variable_set::get"></a><p>
You can get the existing variables with the following functions:
</p>
<pre class="programlisting"><span class="identifier">xpath_variable</span><span class="special">*</span> <span class="identifier">xpath_variable_set</span><span class="special">::</span><span class="identifier">get</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">name</span><span class="special">);</span>
<span class="keyword">const</span> <span class="identifier">xpath_variable</span><span class="special">*</span> <span class="identifier">xpath_variable_set</span><span class="special">::</span><span class="identifier">get</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">name</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
</pre>
<p>
The functions return the variable handle, or null pointer if the variable
with the specified name is not found.
</p>
<a name="xpath_variable_set::set"></a><p>
Additionally, there are the helper functions for setting the variable value
by name; they try to add the variable with the corresponding type, if it
does not exist, and to set the value. If the variable with the same name
but with different type is already present, they return <code class="computeroutput"><span class="keyword">false</span></code>;
they also return <code class="computeroutput"><span class="keyword">false</span></code> on allocation
failure. Note that these functions do not perform any type conversions.
</p>
<pre class="programlisting"><span class="keyword">bool</span> <span class="identifier">xpath_variable_set</span><span class="special">::</span><span class="identifier">set</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">name</span><span class="special">,</span> <span class="keyword">bool</span> <span class="identifier">value</span><span class="special">);</span>
<span class="keyword">bool</span> <span class="identifier">xpath_variable_set</span><span class="special">::</span><span class="identifier">set</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">name</span><span class="special">,</span> <span class="keyword">double</span> <span class="identifier">value</span><span class="special">);</span>
<span class="keyword">bool</span> <span class="identifier">xpath_variable_set</span><span class="special">::</span><span class="identifier">set</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">name</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">value</span><span class="special">);</span>
<span class="keyword">bool</span> <span class="identifier">xpath_variable_set</span><span class="special">::</span><span class="identifier">set</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">name</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">xpath_node_set</span><span class="special">&</span> <span class="identifier">value</span><span class="special">);</span>
</pre>
<p>
The variable values are copied to the internal variable storage, so you can
modify or destroy them after the functions return.
</p>
<a name="xpath_variable"></a><p>
If setting variables by name is not efficient enough, or if you have to inspect
variable information or get variable values, you can use variable handles.
A variable corresponds to the <code class="computeroutput"><span class="identifier">xpath_variable</span></code>
type, and a variable handle is simply a pointer to <code class="computeroutput"><span class="identifier">xpath_variable</span></code>.
</p>
<a name="xpath_variable::type"></a><a name="xpath_variable::name"></a><p>
In order to get variable information, you can use one of the following functions:
</p>
<pre class="programlisting"><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">xpath_variable</span><span class="special">::</span><span class="identifier">name</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
<span class="identifier">xpath_value_type</span> <span class="identifier">xpath_variable</span><span class="special">::</span><span class="identifier">type</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
</pre>
<p>
Note that each variable has a distinct type which is specified upon variable
creation and can not be changed later.
</p>
<a name="xpath_variable::get_boolean"></a><a name="xpath_variable::get_number"></a><a name="xpath_variable::get_string"></a><a name="xpath_variable::get_node_set"></a><p>
In order to get variable value, you should use one of the following functions,
depending on the variable type:
</p>
<pre class="programlisting"><span class="keyword">bool</span> <span class="identifier">xpath_variable</span><span class="special">::</span><span class="identifier">get_boolean</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
<span class="keyword">double</span> <span class="identifier">xpath_variable</span><span class="special">::</span><span class="identifier">get_number</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
<span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">xpath_variable</span><span class="special">::</span><span class="identifier">get_string</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
<span class="keyword">const</span> <span class="identifier">xpath_node_set</span><span class="special">&</span> <span class="identifier">xpath_variable</span><span class="special">::</span><span class="identifier">get_node_set</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
</pre>
<p>
These functions return the value of the variable. Note that no type conversions
are performed; if the type mismatch occurs, a dummy value is returned (<code class="computeroutput"><span class="keyword">false</span></code> for booleans, <code class="computeroutput"><span class="identifier">NaN</span></code>
for numbers, empty string for strings and empty set for node sets).
</p>
<a name="xpath_variable::set"></a><p>
In order to set variable value, you should use one of the following functions,
depending on the variable type:
</p>
<pre class="programlisting"><span class="keyword">bool</span> <span class="identifier">xpath_variable</span><span class="special">::</span><span class="identifier">set</span><span class="special">(</span><span class="keyword">bool</span> <span class="identifier">value</span><span class="special">);</span>
<span class="keyword">bool</span> <span class="identifier">xpath_variable</span><span class="special">::</span><span class="identifier">set</span><span class="special">(</span><span class="keyword">double</span> <span class="identifier">value</span><span class="special">);</span>
<span class="keyword">bool</span> <span class="identifier">xpath_variable</span><span class="special">::</span><span class="identifier">set</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">value</span><span class="special">);</span>
<span class="keyword">bool</span> <span class="identifier">xpath_variable</span><span class="special">::</span><span class="identifier">set</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">xpath_node_set</span><span class="special">&</span> <span class="identifier">value</span><span class="special">);</span>
</pre>
<p>
These functions modify the variable value. Note that no type conversions
are performed; if the type mismatch occurs, the functions return <code class="computeroutput"><span class="keyword">false</span></code>; they also return <code class="computeroutput"><span class="keyword">false</span></code>
on allocation failure. The variable values are copied to the internal variable
storage, so you can modify or destroy them after the functions return.
</p>
<p>
This is an example of using variables in XPath queries (<a href="../samples/xpath_variables.cpp" target="_top">samples/xpath_variables.cpp</a>):
</p>
<p>
</p>
<pre class="programlisting"><span class="comment">// Select nodes via compiled query
</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xpath_variable_set</span> <span class="identifier">vars</span><span class="special">;</span>
<span class="identifier">vars</span><span class="special">.</span><span class="identifier">add</span><span class="special">(</span><span class="string">"remote"</span><span class="special">,</span> <span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xpath_type_boolean</span><span class="special">);</span>
<span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xpath_query</span> <span class="identifier">query_remote_tools</span><span class="special">(</span><span class="string">"/Profile/Tools/Tool[@AllowRemote = string($remote)]"</span><span class="special">,</span> <span class="special">&</span><span class="identifier">vars</span><span class="special">);</span>
<span class="identifier">vars</span><span class="special">.</span><span class="identifier">set</span><span class="special">(</span><span class="string">"remote"</span><span class="special">,</span> <span class="keyword">true</span><span class="special">);</span>
<span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xpath_node_set</span> <span class="identifier">tools_remote</span> <span class="special">=</span> <span class="identifier">query_remote_tools</span><span class="special">.</span><span class="identifier">evaluate_node_set</span><span class="special">(</span><span class="identifier">doc</span><span class="special">);</span>
<span class="identifier">vars</span><span class="special">.</span><span class="identifier">set</span><span class="special">(</span><span class="string">"remote"</span><span class="special">,</span> <span class="keyword">false</span><span class="special">);</span>
<span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xpath_node_set</span> <span class="identifier">tools_local</span> <span class="special">=</span> <span class="identifier">query_remote_tools</span><span class="special">.</span><span class="identifier">evaluate_node_set</span><span class="special">(</span><span class="identifier">doc</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"Remote tool: "</span><span class="special">;</span>
<span class="identifier">tools_remote</span><span class="special">[</span><span class="number">2</span><span class="special">].</span><span class="identifier">node</span><span class="special">().</span><span class="identifier">print</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"Local tool: "</span><span class="special">;</span>
<span class="identifier">tools_local</span><span class="special">[</span><span class="number">0</span><span class="special">].</span><span class="identifier">node</span><span class="special">().</span><span class="identifier">print</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special">);</span>
<span class="comment">// You can pass the context directly to select_nodes/select_node
</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xpath_node_set</span> <span class="identifier">tools_local_imm</span> <span class="special">=</span> <span class="identifier">doc</span><span class="special">.</span><span class="identifier">select_nodes</span><span class="special">(</span><span class="string">"/Profile/Tools/Tool[@AllowRemote = string($remote)]"</span><span class="special">,</span> <span class="special">&</span><span class="identifier">vars</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"Local tool imm: "</span><span class="special">;</span>
<span class="identifier">tools_local_imm</span><span class="special">[</span><span class="number">0</span><span class="special">].</span><span class="identifier">node</span><span class="special">().</span><span class="identifier">print</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special">);</span>
</pre>
<p>
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="manual.xpath.errors"></a><a class="link" href="xpath.html#manual.xpath.errors" title="Error handling"> Error handling</a>
</h3></div></div></div>
<p>
There are two different mechanisms for error handling in XPath implementation;
the mechanism used depends on whether exception support is disabled (this
is controlled with <a class="link" href="install.html#PUGIXML_NO_EXCEPTIONS">PUGIXML_NO_EXCEPTIONS</a>
define).
</p>
<a name="xpath_exception"></a><a name="xpath_exception::result"></a><a name="xpath_exception::what"></a><p>
By default, XPath functions throw <code class="computeroutput"><span class="identifier">xpath_exception</span></code>
object in case of errors; additionally, in the event any memory allocation
fails, an <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">bad_alloc</span></code> exception is thrown. Also <code class="computeroutput"><span class="identifier">xpath_exception</span></code> is thrown if the query
is evaluated to a node set, but the return type is not node set. If the query
constructor succeeds (i.e. no exception is thrown), the query object is valid.
Otherwise you can get the error details via one of the following functions:
</p>
<pre class="programlisting"><span class="keyword">virtual</span> <span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">xpath_exception</span><span class="special">::</span><span class="identifier">what</span><span class="special">()</span> <span class="keyword">const</span> <span class="keyword">throw</span><span class="special">();</span>
<span class="keyword">const</span> <span class="identifier">xpath_parse_result</span><span class="special">&</span> <span class="identifier">xpath_exception</span><span class="special">::</span><span class="identifier">result</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
</pre>
<a name="xpath_query::unspecified_bool_type"></a><a name="xpath_query::result"></a><p>
If exceptions are disabled, then in the event of parsing failure the query
is initialized to invalid state; you can test if the query object is valid
by using it in a boolean expression: <code class="computeroutput"><span class="keyword">if</span>
<span class="special">(</span><span class="identifier">query</span><span class="special">)</span> <span class="special">{</span> <span class="special">...</span>
<span class="special">}</span></code>. Additionally, you can get parsing
result via the result() accessor:
</p>
<pre class="programlisting"><span class="keyword">const</span> <span class="identifier">xpath_parse_result</span><span class="special">&</span> <span class="identifier">xpath_query</span><span class="special">::</span><span class="identifier">result</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
</pre>
<p>
Without exceptions, evaluating invalid query results in <code class="computeroutput"><span class="keyword">false</span></code>,
empty string, NaN or an empty node set, depending on the type; evaluating
a query as a node set results in an empty node set if the return type is
not node set.
</p>
<a name="xpath_parse_result"></a><p>
The information about parsing result is returned via <code class="computeroutput"><span class="identifier">xpath_parse_result</span></code>
object. It contains parsing status and the offset of last successfully parsed
character from the beginning of the source stream:
</p>
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">xpath_parse_result</span>
<span class="special">{</span>
<span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">error</span><span class="special">;</span>
<span class="identifier">ptrdiff_t</span> <span class="identifier">offset</span><span class="special">;</span>
<span class="keyword">operator</span> <span class="keyword">bool</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
<span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">description</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
<span class="special">};</span>
</pre>
<a name="xpath_parse_result::error"></a><p>
Parsing result is represented as the error message; it is either a null pointer,
in case there is no error, or the error message in the form of ASCII zero-terminated
string.
</p>
<a name="xpath_parse_result::description"></a><p>
<code class="computeroutput"><span class="identifier">description</span><span class="special">()</span></code>
member function can be used to get the error message; it never returns the
null pointer, so you can safely use <code class="computeroutput"><span class="identifier">description</span><span class="special">()</span></code> even if query parsing succeeded. Note that
<code class="computeroutput"><span class="identifier">description</span><span class="special">()</span></code>
returns a <code class="computeroutput"><span class="keyword">char</span></code> string even in
<code class="computeroutput"><span class="identifier">PUGIXML_WCHAR_MODE</span></code>; you'll
have to call <a class="link" href="dom.html#as_wide">as_wide</a> to get the <code class="computeroutput"><span class="keyword">wchar_t</span></code> string.
</p>
<a name="xpath_parse_result::offset"></a><p>
In addition to the error message, parsing result has an <code class="computeroutput"><span class="identifier">offset</span></code>
member, which contains the offset of last successfully parsed character.
This offset is in units of <a class="link" href="dom.html#char_t">pugi::char_t</a> (bytes
for character mode, wide characters for wide character mode).
</p>
<a name="xpath_parse_result::bool"></a><p>
Parsing result object can be implicitly converted to <code class="computeroutput"><span class="keyword">bool</span></code>
like this: <code class="computeroutput"><span class="keyword">if</span> <span class="special">(</span><span class="identifier">result</span><span class="special">)</span> <span class="special">{</span> <span class="special">...</span> <span class="special">}</span>
<span class="keyword">else</span> <span class="special">{</span> <span class="special">...</span> <span class="special">}</span></code>.
</p>
<p>
This is an example of XPath error handling (<a href="../samples/xpath_error.cpp" target="_top">samples/xpath_error.cpp</a>):
</p>
<p>
</p>
<pre class="programlisting"><span class="comment">// Exception is thrown for incorrect query syntax
</span><span class="keyword">try</span>
<span class="special">{</span>
<span class="identifier">doc</span><span class="special">.</span><span class="identifier">select_nodes</span><span class="special">(</span><span class="string">"//nodes[#true()]"</span><span class="special">);</span>
<span class="special">}</span>
<span class="keyword">catch</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xpath_exception</span><span class="special">&</span> <span class="identifier">e</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"Select failed: "</span> <span class="special"><<</span> <span class="identifier">e</span><span class="special">.</span><span class="identifier">what</span><span class="special">()</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="special">}</span>
<span class="comment">// Exception is thrown for incorrect query semantics
</span><span class="keyword">try</span>
<span class="special">{</span>
<span class="identifier">doc</span><span class="special">.</span><span class="identifier">select_nodes</span><span class="special">(</span><span class="string">"(123)/next"</span><span class="special">);</span>
<span class="special">}</span>
<span class="keyword">catch</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xpath_exception</span><span class="special">&</span> <span class="identifier">e</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"Select failed: "</span> <span class="special"><<</span> <span class="identifier">e</span><span class="special">.</span><span class="identifier">what</span><span class="special">()</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="special">}</span>
<span class="comment">// Exception is thrown for query with incorrect return type
</span><span class="keyword">try</span>
<span class="special">{</span>
<span class="identifier">doc</span><span class="special">.</span><span class="identifier">select_nodes</span><span class="special">(</span><span class="string">"123"</span><span class="special">);</span>
<span class="special">}</span>
<span class="keyword">catch</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xpath_exception</span><span class="special">&</span> <span class="identifier">e</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"Select failed: "</span> <span class="special"><<</span> <span class="identifier">e</span><span class="special">.</span><span class="identifier">what</span><span class="special">()</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="special">}</span>
</pre>
<p>
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="manual.xpath.w3c"></a><a class="link" href="xpath.html#manual.xpath.w3c" title="Conformance to W3C specification"> Conformance to W3C specification</a>
</h3></div></div></div>
<p>
Because of the differences in document object models, performance considerations
and implementation complexity, pugixml does not provide a fully conformant
XPath 1.0 implementation. This is the current list of incompatibilities:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
Consecutive text nodes sharing the same parent are not merged, i.e. in
<code class="computeroutput"><span class="special"><</span><span class="identifier">node</span><span class="special">></span><span class="identifier">text1</span>
<span class="special"><![</span><span class="identifier">CDATA</span><span class="special">[</span><span class="identifier">data</span><span class="special">]]></span> <span class="identifier">text2</span><span class="special"></</span><span class="identifier">node</span><span class="special">></span></code> node should have one text node child,
but instead has three.
</li>
<li class="listitem">
Since the document type declaration is not used for parsing, <code class="computeroutput"><span class="identifier">id</span><span class="special">()</span></code>
function always returns an empty node set.
</li>
<li class="listitem">
Namespace nodes are not supported (affects namespace:: axis).
</li>
<li class="listitem">
Name tests are performed on QNames in XML document instead of expanded
names; for <code class="computeroutput"><span class="special"><</span><span class="identifier">foo</span>
<span class="identifier">xmlns</span><span class="special">:</span><span class="identifier">ns1</span><span class="special">=</span><span class="char">'uri'</span> <span class="identifier">xmlns</span><span class="special">:</span><span class="identifier">ns2</span><span class="special">=</span><span class="char">'uri'</span><span class="special">><</span><span class="identifier">ns1</span><span class="special">:</span><span class="identifier">child</span><span class="special">/><</span><span class="identifier">ns2</span><span class="special">:</span><span class="identifier">child</span><span class="special">/></</span><span class="identifier">foo</span><span class="special">></span></code>,
query <code class="computeroutput"><span class="identifier">foo</span><span class="special">/</span><span class="identifier">ns1</span><span class="special">:*</span></code>
will return only the first child, not both of them. Compliant XPath implementations
can return both nodes if the user provides appropriate namespace declarations.
</li>
<li class="listitem">
String functions consider a character to be either a single <code class="computeroutput"><span class="keyword">char</span></code> value or a single <code class="computeroutput"><span class="keyword">wchar_t</span></code>
value, depending on the library configuration; this means that some string
functions are not fully Unicode-aware. This affects <code class="computeroutput"><span class="identifier">substring</span><span class="special">()</span></code>, <code class="computeroutput"><span class="identifier">string</span><span class="special">-</span><span class="identifier">length</span><span class="special">()</span></code> and <code class="computeroutput"><span class="identifier">translate</span><span class="special">()</span></code> functions.
</li>
</ul></div>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright © 2014 Arseny Kapoulkine<p>
Distributed under the MIT License
</p>
</div></td>
</tr></table>
<hr>
<table width="100%"><tr>
<td>
<a href="http://pugixml.org/">pugixml 1.6</a> manual |
<a href="../manual.html">Overview</a> |
<a href="install.html">Installation</a> |
Document:
<a href="dom.html">Object model</a> · <a href="loading.html">Loading</a> · <a href="access.html">Accessing</a> · <a href="modify.html">Modifying</a> · <a href="saving.html">Saving</a> |
<b>XPath</b> |
<a href="apiref.html">API Reference</a> |
<a href="toc.html">Table of Contents</a>
</td>
<td width="*" align="right"><div class="spirit-nav">
<a accesskey="p" href="saving.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../manual.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../manual.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="changes.html"><img src="../images/next.png" alt="Next"></a>
</div></td>
</tr></table>
</body>
</html>
|