-
Notifications
You must be signed in to change notification settings - Fork 0
/
xep-0030.xml
1005 lines (979 loc) · 54.6 KB
/
xep-0030.xml
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
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE xep SYSTEM 'xep.dtd' [
<!ENTITY % ents SYSTEM 'xep.ent'>
%ents;
]>
<?xml-stylesheet type='text/xsl' href='xep.xsl'?>
<xep>
<header>
<title>Service Discovery</title>
<abstract>This specification defines an XMPP protocol extension for discovering information about other XMPP entities. Two kinds of information can be discovered: (1) the identity and capabilities of an entity, including the protocols and features it supports; and (2) the items associated with an entity, such as the list of rooms hosted at a multi-user chat service.</abstract>
&LEGALNOTICE;
<number>0030</number>
<status>Final</status>
<interim/>
<type>Standards Track</type>
<sig>Standards</sig>
<approver>Council</approver>
<dependencies>
<spec>XMPP Core</spec>
</dependencies>
<supersedes>
<spec>XEP-0011</spec>
<spec>XEP-0094</spec>
</supersedes>
<supersededby/>
<shortname>disco</shortname>
<schemaloc>
<ns>http://jabber.org/protocol/disco#info</ns>
<url>http://www.xmpp.org/schemas/disco-info.xsd</url>
</schemaloc>
<schemaloc>
<ns>http://jabber.org/protocol/disco#items</ns>
<url>http://www.xmpp.org/schemas/disco-items.xsd</url>
</schemaloc>
<registry/>
&hildjj;
&pgmillard;
&reatmon;
&stpeter;
<revision>
<version>2.5.0</version>
<date>2024-04-30</date>
<initials>pep</initials>
<remark><p>Add note about some entities not advertising the <tt>http://jabber.org/protocol/disco#info</tt> feature.</p></remark>
</revision>
<revision>
<version>2.5rc3</version>
<date>2017-10-03</date>
<initials>th</initials>
<remark><p>XML schema modified so that no ordering is required between disco#info children.</p></remark>
</revision>
<revision>
<version>2.5rc2</version>
<date>2016-10-13</date>
<initials>egp</initials>
<remark>
<p>Fixed the examples to always include a disco#info feature.</p>
<p>Listed the proper namespace in the schemaloc ns element.</p>
</remark>
</revision>
<revision>
<version>2.5rc1</version>
<date>2015-09-22</date>
<initials>editor(mam)</initials>
<remark>
<p>Errata submitted to standards@ regarding subscriptions and returned items.</p>
<p>Clarify that feature elements must be childless to make the text match the schema.</p>
</remark>
</revision>
<revision>
<version>2.4</version>
<date>2008-06-06</date>
<initials>psa</initials>
<remark><p>Per Council consensus, removed disco-publish feature (implementations should use publish-subscribe instead).</p></remark>
</revision>
<revision>
<version>2.3</version>
<date>2007-02-15</date>
<initials>psa</initials>
<remark><p>Added implementation note regarding Entity Capabilities.</p></remark>
</revision>
<revision>
<version>2.2</version>
<date>2006-01-24</date>
<initials>psa</initials>
<remark><p>Further specified and clarified security considerations relating to server handling of requests sent to bare JIDs.</p></remark>
</revision>
<revision>
<version>2.1</version>
<date>2005-03-03</date>
<initials>psa</initials>
<remark><p>Added paragraph to implementation notes about server handling of requests sent to bare JIDs.</p></remark>
</revision>
<revision>
<version>2.0</version>
<date>2004-07-20</date>
<initials>psa</initials>
<remark><p>Per a vote of the Jabber Council, advanced status to Final.</p></remark>
</revision>
<revision>
<version>1.10</version>
<date>2004-06-29</date>
<initials>psa/jjh</initials>
<remark><p>Defined security considerations; changed extended presence example to use a fictitious protocol; further specified publish feature; defined registry submissions.</p></remark>
</revision>
<revision>
<version>1.9</version>
<date>2004-05-27</date>
<initials>psa</initials>
<remark><p>Clarified error conditions.</p></remark>
</revision>
<revision>
<version>1.8</version>
<date>2004-05-21</date>
<initials>psa</initials>
<remark><p>Moved remaining feature negotiation text to XEP-0020.</p></remark>
</revision>
<revision>
<version>1.7</version>
<date>2004-05-13</date>
<initials>psa</initials>
<remark><p>Added implementation note regarding flexibility of feature and item results; final editorial cleanup.</p></remark>
</revision>
<revision>
<version>1.6</version>
<date>2004-05-11</date>
<initials>psa</initials>
<remark><p>Corrected examples of publishing available items; further clarified nature of node hierarchies.</p></remark>
</revision>
<revision>
<version>1.5</version>
<date>2004-05-10</date>
<initials>psa</initials>
<remark><p>Added clarifying note about node hierarchies.</p></remark>
</revision>
<revision>
<version>1.4</version>
<date>2004-05-07</date>
<initials>psa</initials>
<remark><p>Clarified usage of "directory"; added section defining the relationship between an entity and its associated items.</p></remark>
</revision>
<revision>
<version>1.3</version>
<date>2004-04-23</date>
<initials>psa</initials>
<remark><p>Further clarified item-publication protocol; moved some feature negotiation text to XEP-0020; added information about registry of well-known service discovery nodes; added implementation notes regarding tree-walking and large result sets; incorporated additional Call for Experience suggestions.</p></remark>
</revision>
<revision>
<version>1.2</version>
<date>2004-04-20</date>
<initials>psa</initials>
<remark><p>Editorial cleanup; incorporated some Call for Experience suggestions.</p></remark>
</revision>
<revision>
<version>1.1</version>
<date>2004-03-15</date>
<initials>psa</initials>
<remark><p>Described requirements, syntax, and use cases in a more formal manner; corrected several errors in the examples and schemas; defined XMPP Registrar procedures; added a number of references; specified XMPP error handling.</p></remark>
</revision>
<revision>
<version>1.0</version>
<date>2003-04-21</date>
<initials>psa</initials>
<remark><p>Per a vote of the Jabber Council, advanced status to Draft; also added XML schemas.</p></remark>
</revision>
<revision>
<version>0.13</version>
<date>2003-02-25</date>
<initials>pgm</initials>
<remark><p>Added remarks about empty node attributes; described semantics regarding multiple identity elements.</p></remark>
</revision>
<revision>
<version>0.12</version>
<date>2003-02-06</date>
<initials>pgm</initials>
<remark><p>Added support for IQ-set; added example for disco#info to a specific node.</p></remark>
</revision>
<revision>
<version>0.11</version>
<date>2002-12-17</date>
<initials>psa</initials>
<remark><p>Added support for the 'node' attribute per discussion on the Standards list in order to support items that are not JID-addressable.</p></remark>
</revision>
<revision>
<version>0.10</version>
<date>2002-11-21</date>
<initials>psa</initials>
<remark><p>Changed <feature type='foo'/> to <feature var='foo'/> to track changes in feature negotiation (XEP-0020); added initial registry parameters.</p></remark>
</revision>
<revision>
<version>0.9</version>
<date>2002-11-07</date>
<initials>psa</initials>
<remark><p>Added support for empty result sets in disco#item.</p></remark>
</revision>
<revision>
<version>0.8</version>
<date>2002-11-01</date>
<initials>psa</initials>
<remark><p>Removed the max, start, and total attributes for item queries (this will be handled by a generic paging protocol); added "http://jabber.org/protocol/feature-neg" namespace as a feature to signal negotiability regarding one or more features.</p></remark>
</revision>
<revision>
<version>0.7</version>
<date>2002-10-28</date>
<initials>psa</initials>
<remark><p>Cleaned up the feature text and examples.</p></remark>
</revision>
<revision>
<version>0.6</version>
<date>2002-10-27</date>
<initials>psa</initials>
<remark><p>Added the 'category' attribute to the <feature/> element; added security, IANA, and XMPP Registrar considerations; added a number of examples.</p></remark>
</revision>
<revision>
<version>0.5</version>
<date>2002-10-15</date>
<initials>psa</initials>
<remark><p>Total overhaul and simplification.</p></remark>
</revision>
<revision>
<version>0.4</version>
<date>2002-07-16</date>
<initials>psa</initials>
<remark><p>Major additions and fixes, many more examples.</p></remark>
</revision>
<revision>
<version>0.3</version>
<date>2002-05-30</date>
<initials>psa</initials>
<remark><p>Re-organized around use cases, made some minor fixes.</p></remark>
</revision>
<revision>
<version>0.2</version>
<date>2002-05-05</date>
<initials>psa</initials>
<remark><p>Incorporated comments from co-authors and added notes.</p></remark>
</revision>
<revision>
<version>0.1</version>
<date>2002-05-03</date>
<initials>psa</initials>
<remark><p>Initial draft.</p></remark>
</revision>
</header>
<section1 topic='Introduction' anchor='intro'>
<p>The ability to discover information about entities on the Jabber network is extremely valuable. Such information might include features offered or protocols supported by the entity, the entity's type or identity, and additional entities that are associated with the original entity in some way (often thought of as "children" of the "parent" entity). While mechanisms for doing so are not defined in &xmppcore;, several protocols have been used in the past within the Jabber community for service discovery, specifically &xep0011; and &xep0094;. However, those protocols are perceived to be inadequate for several reasons:</p>
<ol>
<li><p>Neither Jabber Browsing nor Agent Information is easily extensible. For example, the categories and subcategories listed for JID-Types in XEP-0011 are explicitly defined as the only official categories, and any additions to the list of JID-Types would require a modification to XEP-0011. While the Jabber Browsing specification does allow for the use of unofficial categories and types prefixed with the string 'x-', this introduces migration issues. This lack of flexibility violates one of the Jabber community's core &xep0134;.</p></li>
<li><p>In Agent Information, there is no way to advertise supported features. While Jabber Browsing includes such a mechanism, the only way to express the availability of a feature is to advertise a supported protocol namespace. Yet some features may not be uniquely associated with a protocol namespace, which are one implementation of features but not the only one.</p></li>
<li><p>A Jabber Browsing result returns a combination of (1) namespaces supported by a Jabber Entity, (2) items associated with a Jabber Entity, and (3) namespaces supported by the associated items. This approach mixes information levels and requires parents to know everything about child nodes, thereby introducing significant confusion.</p></li>
<li><p>In both Jabber Browsing and Agent Information, items must be addressable as JIDs; however, this may not be possible in some applications.</p></li>
</ol>
<p>This document addresses the perceived weaknesses of both the Jabber Browsing and Agent Information protocols. The result is a standards-track protocol for service discovery (often abbreviated to "disco", as is familiar in protocols such as &w3soap;).</p>
</section1>
<section1 topic='Requirements' anchor='reqs'>
<p>The authors have designed the service discovery protocol with the following requirements in mind:</p>
<ul>
<li><p>The protocol MUST support all functionality supported by the protocols it supersedes (Jabber Browsing and Agent Information).</p></li>
<li>
<p>There are three kinds of information that need to be discovered about an entity:</p>
<ol>
<li>its basic identity (type and/or category)</li>
<li>the features it offers and protocols it supports</li>
<li>any additional items associated with the entity, whether or not they are addressable as JIDs</li>
</ol>
<p>All three MUST be supported, but the first two kinds of information relate to the entity itself whereas the third kind of information relates to items associated with the entity itself; therefore two different query types are needed.</p>
</li>
<li><p>Discovering information about a child item MUST be accomplished by sending a separate discovery request to that item, not to the parent entity. (One result of this is that discovering complete information about an entire tree will require multiple request/response pairs in order to "walk the tree".)</p></li>
<li><p>The lists of identities and features MUST be flexible.</p></li>
<li><p>The protocol itself MUST be extensible.</p></li>
</ul>
</section1>
<section1 topic='Discovering Information About a Jabber Entity' anchor='info'>
<section2 topic='Basic Protocol' anchor='info-basic'>
<p>A requesting entity may want to discover information about another entity on the network. The information desired generally is of two kinds:</p>
<ol>
<li><p><strong>The target entity's identity.</strong> In disco, an entity's identity is broken down into its category (server, client, gateway, directory, etc.) and its particular type within that category (IM server, phone vs. handheld client, MSN gateway vs. AIM gateway, user directory vs. chatroom directory, etc.). This information helps requesting entities to determine the group or "bucket" of services into which the entity is most appropriately placed (e.g., perhaps the entity is shown in a GUI with an appropriate icon). An entity MAY have multiple identities. When multiple identity elements are provided, the name attributes for each identity element SHOULD have the same value.</p>
</li>
<li><p><strong>The features offered and protocols supported by the target entity.</strong> This information helps requesting entities determine what actions are possible with regard to this entity (registration, search, join, etc.), what protocols the entity supports, and specific feature types of interest, if any (e.g., for the purpose of feature negotiation).</p></li>
</ol>
<p>In order to discover such information, the requesting entity MUST send an IQ stanza of type "get", containing an empty <query/> element qualified by the 'http://jabber.org/protocol/disco#info' namespace, to the JID of the target entity (a 'node' attribute on the &QUERY; element is OPTIONAL as described in the <link url="#info-nodes">Info Nodes</link> and <link url="#items-nodes">Items Nodes</link> section of this document):</p>
<example caption='Querying for information'><![CDATA[
<iq type='get'
from='[email protected]/orchard'
to='plays.shakespeare.lit'
id='info1'>
<query xmlns='http://jabber.org/protocol/disco#info'/>
</iq>
]]></example>
<p>The target entity then MUST either return an IQ result, or return an error (see the <link url="#errors">Error Conditions</link> section of this document). The result MUST contain a <query/> element qualified by the 'http://jabber.org/protocol/disco#info' namespace, which in turn contains one or more <identity/> elements and one or more <feature/> elements. (Note: Every entity MUST have at least one identity, and every entity MUST support at least the 'http://jabber.org/protocol/disco#info' feature; however, an entity is not required to return a result and MAY return an error, most likely &feature; or &unavailable;, although other error conditions may be appropriate.)</p>
<div class="box"><p>Note: Some entities are known not to advertise the <tt>http://jabber.org/protocol/disco#info</tt> feature within their responses, contrary to this specification. Entities receiving otherwise valid responses which do not include this feature SHOULD infer the support.</p></div>
<p>Each <identity/> element MUST possess the 'category' and 'type' attributes specifying the category and type for the entity, and MAY possess a 'name' attribute specifying a natural-language name for the entity; the <identity/> element MAY also possess a standard 'xml:lang' attribute, which enables the entity to return localized results if desired (i.e., the <query/> element MAY include multiple <identity/> elements with the same category+type but with different 'xml:lang' values, however the <query/> element MUST NOT include multiple <identity/> elements with the same category+type+xml:lang but with different 'name' values).</p>
<p>Each <feature/> element MUST possess a 'var' attribute whose value is a protocol namespace or other feature offered by the entity, and MUST NOT have any children.</p>
<p>Preferably, both the category/type values and the feature values will be registered in a public registry, as described in the <link url="#registrar">XMPP Registrar Considerations</link> section of this document.</p>
<example caption='Result-set for information request'><![CDATA[
<iq type='result'
from='plays.shakespeare.lit'
to='[email protected]/orchard'
id='info1'>
<query xmlns='http://jabber.org/protocol/disco#info'>
<identity
category='conference'
type='text'
name='Play-Specific Chatrooms'/>
<identity
category='directory'
type='chatroom'
name='Play-Specific Chatrooms'/>
<feature var='http://jabber.org/protocol/disco#info'/>
<feature var='http://jabber.org/protocol/disco#items'/>
<feature var='http://jabber.org/protocol/muc'/>
<feature var='jabber:iq:register'/>
<feature var='jabber:iq:search'/>
<feature var='jabber:iq:time'/>
<feature var='jabber:iq:version'/>
</query>
</iq>
]]></example>
<p>If the JID of the specified target entity does not exist, the server or other authoritative entity SHOULD return an ¬found; error, unless doing so would violate the privacy and security considerations specified in <cite>XMPP Core</cite> and &xmppim; or local privacy and security policies (see also the <link url='#security'>Security Considerations</link> of this document):</p>
<example caption='Target entity does not exist'><![CDATA[
<iq type='error'
from='plays.shakespeare.lit'
to='[email protected]/orchard'
id='info1'>
<query xmlns='http://jabber.org/protocol/disco#info'/>
<error type='cancel'>
<item-not-found xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
</error>
</iq>
]]></example>
<p>If privacy and security considerations or policies prevent the server or other authoritative entity from returning an ¬found; error, it SHOULD return a &unavailable; error instead:</p>
<example caption='Service unavailable'><![CDATA[
<iq type='error'
from='plays.shakespeare.lit'
to='[email protected]/orchard'
id='info1'>
<query xmlns='http://jabber.org/protocol/disco#info'/>
<error type='cancel'>
<service-unavailable xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
</error>
</iq>
]]></example>
<p>When an entity sends a disco#info request to a bare JID (<[email protected]>) hosted by a server, the server itself MUST reply on behalf of the hosted account, either with an IQ-error or an IQ-result. For important rules regarding access to this functionality, see the <link url='#security'>Security Considerations</link> section of this document. In particular, in response to a disco#info request sent to a bare JID with no node, if access is not denied the server SHOULD return an IQ-result for the bare JID, in which the primary identity SHOULD have a category of "account" with an appropriate type as specified in the Service Discovery Identities registry (most likely, a type of "registered"). Note: This enables authorized or trusted entities to discover whether the account exists and its account type (e.g., in IM systems to determine the existence of an account before adding it to a contact's roster).</p>
<example caption='Requesting info from a bare JID'><![CDATA[
<iq type='get'
from='shakespeare.lit'
to='[email protected]'
id='info2'>
<query xmlns='http://jabber.org/protocol/disco#info'/>
</iq>
]]></example>
<p>Here we assume that shakespeare.lit is trusted by capulet.com and that the account <[email protected]> is a registered account:</p>
<example caption='Server replies on behalf of bare JID'><![CDATA[
<iq type='result'
from='[email protected]'
to='shakespeare.lit'
id='info2'>
<query xmlns='http://jabber.org/protocol/disco#info'>
<identity category='account' type='registered'/>
<feature var='http://jabber.org/protocol/disco#info'/>
</query>
</iq>
]]></example>
<p>A query sent to an associated entity may result in different or more detailed information. One example is sending a query to a particular conference room rather than the parent conference service:</p>
<example caption='Querying a specific conference room'><![CDATA[
<iq type='get'
from='[email protected]/balcony'
to='[email protected]'
id='info3'>
<query xmlns='http://jabber.org/protocol/disco#info'/>
</iq>
<iq type='result'
from='[email protected]'
to='[email protected]/balcony'
id='info3'>
<query xmlns='http://jabber.org/protocol/disco#info'>
<identity
category='conference'
name='A Dark Cave'
type='text'/>
<feature var='http://jabber.org/protocol/disco#info'/>
<feature var='http://jabber.org/protocol/muc'/>
<feature var='muc_passwordprotected'/>
<feature var='muc_hidden'/>
<feature var='muc_temporary'/>
<feature var='muc_open'/>
<feature var='muc_unmoderated'/>
<feature var='muc_nonanonymous'/>
</query>
</iq>]]></example>
<p>Another example of this is sending a query to a specific connected resource for an IM user:</p>
<example caption='Querying a connected resource for further information'><![CDATA[
<iq type='get'
from='[email protected]/balcony'
to='[email protected]/orchard'
id='info4'>
<query xmlns='http://jabber.org/protocol/disco#info'/>
</iq>
<iq type='result'
from='[email protected]/orchard'
to='[email protected]/balcony'
id='info4'>
<query xmlns='http://jabber.org/protocol/disco#info'>
<identity
category='client'
type='pc'
name='Gabber'/>
<feature var='http://jabber.org/protocol/disco#info'/>
<feature var='jabber:iq:time'/>
<feature var='jabber:iq:version'/>
</query>
</iq>
]]></example>
</section2>
<section2 topic='Info Nodes' anchor='info-nodes'>
<p>A disco#info query MAY also be directed to a specific node identifier associated with a JID, although the primary use of nodes is as <link url='#items-nodes'>Items Nodes</link> rather than as info nodes:</p>
<example caption='Querying a specific JID and node combination'><![CDATA[
<iq type='get'
from='[email protected]/orchard'
to='mim.shakespeare.lit'
id='info3'>
<query xmlns='http://jabber.org/protocol/disco#info'
node='http://jabber.org/protocol/commands'/>
</iq>
]]></example>
<p>If the request included a 'node' attribute, the response MUST mirror the specified 'node' attribute to ensure coherence between the request and the response.</p>
<example caption='JID+node result'><![CDATA[
<iq type='result'
from='mim.shakespeare.lit'
to='[email protected]/orchard'
id='info3'>
<query xmlns='http://jabber.org/protocol/disco#info'
node='http://jabber.org/protocol/commands'>
<identity
category='automation'
type='command-list'/>
<feature var='http://jabber.org/protocol/disco#info'/>
</query>
</iq>
]]></example>
</section2>
</section1>
<section1 topic='Discovering the Items Associated with a Jabber Entity' anchor='items'>
<section2 topic='Basic Protocol' anchor='items-basic'>
<p>In order for the requesting entity to discover the items associated with a Jabber Entity, it MUST send an IQ stanza of type "get" to the target entity, containing an empty <query/> element qualified by the 'http://jabber.org/protocol/disco#items' namespace:</p>
<example caption='Requesting all items'><![CDATA[
<iq type='get'
from='[email protected]/orchard'
to='shakespeare.lit'
id='items1'>
<query xmlns='http://jabber.org/protocol/disco#items'/>
</iq>
]]></example>
<p>The target entity then MUST either return its list of publicly-available items, or return an error. The list of items MUST be provided in an IQ stanza of type "result", with each item specified by means of an <item/> child of a <query/> element qualified by the 'http://jabber.org/protocol/disco#items' namespace (the <item/> child MUST possess a 'jid' attribute specifying the JID of the item and MAY possess a 'name' attribute specifying a natural-language name for the item):</p>
<example caption='Result-set for all items'><![CDATA[
<iq type='result'
from='shakespeare.lit'
to='[email protected]/orchard'
id='items1'>
<query xmlns='http://jabber.org/protocol/disco#items'>
<item jid='people.shakespeare.lit'
name='Directory of Characters'/>
<item jid='plays.shakespeare.lit'
name='Play-Specific Chatrooms'/>
<item jid='mim.shakespeare.lit'
name='Gateway to Marlowe IM'/>
<item jid='words.shakespeare.lit'
name='Shakespearean Lexicon'/>
<item jid='globe.shakespeare.lit'
name='Calendar of Performances'/>
<item jid='headlines.shakespeare.lit'
name='Latest Shakespearean News'/>
<item jid='catalog.shakespeare.lit'
name='Buy Shakespeare Stuff!'/>
<item jid='en2fr.shakespeare.lit'
name='French Translation Service'/>
</query>
</iq>
]]></example>
<p>The <item/> element MUST NOT contain XML character data and SHOULD be empty; while it MAY contain XML data in another namespace, such data MUST be ignored if an implementation does not understand it.</p>
<p>If there are no items associated with an entity (or if those items are not publicly available), the target entity MUST return an empty query element to the requesting entity:</p>
<example caption='Empty result set'><![CDATA[
<iq type='result'
from='shakespeare.lit'
to='[email protected]/orchard'
id='items1'>
<query xmlns='http://jabber.org/protocol/disco#items'/>
</iq>
]]></example>
<p>As with disco#info requests, when an entity sends a disco#items request to a bare JID (<[email protected]>) hosted by a server, the server itself MUST reply on behalf of the hosted account. For important rules regarding access to this functionality, see the <link url='#security'>Security Considerations</link> section of this document. In particular, in response to a disco#items request sent to a bare JID with no node, if access is not denied the server SHOULD return the associated items including connected or available resources as appropriate:</p>
<example caption='Requesting items from a bare JID'><![CDATA[
<iq type='get'
from='shakespeare.lit'
to='[email protected]'
id='items2'>
<query xmlns='http://jabber.org/protocol/disco#items'/>
</iq>
]]></example>
<p>Here we assume that shakespeare.lit is trusted by capulet.com and that the account <[email protected]> has two available resources:</p>
<example caption='Server replies on behalf of bare JID'><![CDATA[
<iq type='result'
from='[email protected]'
to='shakespeare.lit'
id='items2'>
<query xmlns='http://jabber.org/protocol/disco#items'>
<item jid='[email protected]/balcony'/>
<item jid='[email protected]/chamber'/>
</query>
</iq>
]]></example>
</section2>
<section2 topic='Items Nodes' anchor='items-nodes'>
<p>It is possible that an item associated with an entity will not be addressable as a JID; examples might include offline messages stored in an inbox (see &xep0013;), entries in a Jabber-enabled weblog, XML-RPC services associated with a client or component, items available in an online trading system (e.g., a catalog or auction), news postings located at an NNTP gateway, and topics hosted by a &xep0060; component. In order to handle such items, the <item/> element MAY possess an OPTIONAL 'node' attribute that supplements the REQUIRED 'jid' attribute.</p>
<p>The value of the node attribute may or may not have semantic meaning; from the perspective of Service Discovery, a node is merely something that is associated with an entity. In order to discover more about the node, the requesting entity MUST query the entity's JID while specifying the node. If the value of the 'node' attribute has semantic meaning, that meaning is provided by the "using protocol" or application, not by the Service Discovery protocol. A node attribute SHOULD NOT be included unless it is necessary to provide or discover information about an entity that cannot be directly addressed as a JID (i.e., if the associated item can be addressed as a JID, do not include a node). The value of the 'node' attribute MUST NOT be null.</p>
<p>In the following example, a user requests all available items from an online catalog service:</p>
<example caption='Requesting nodes'><![CDATA[
<iq type='get'
from='[email protected]/orchard'
to='catalog.shakespeare.lit'
id='items2'>
<query xmlns='http://jabber.org/protocol/disco#items'/>
</iq>
]]></example>
<p>If there are items associated with the target entity but they are not addressable as JIDs, the service SHOULD then return a list of nodes (where each <item/> element MUST possess a 'jid' attribute, SHOULD possess a 'node' attribute, and MAY possess a 'name' attribute):</p>
<example caption='Service returns nodes'><![CDATA[
<iq type='result'
from='catalog.shakespeare.lit'
to='[email protected]/orchard'
id='items2'>
<query xmlns='http://jabber.org/protocol/disco#items'>
<item jid='catalog.shakespeare.lit'
node='books'
name='Books by and about Shakespeare'/>
<item jid='catalog.shakespeare.lit'
node='clothing'
name='Wear your literary taste with pride'/>
<item jid='catalog.shakespeare.lit'
node='music'
name='Music from the time of Shakespeare'/>
</query>
</iq>
]]></example>
<p>There may be futher nodes associated with the "first-level" nodes returned in the above query (e.g., the nodes may be categories that have associated items). The requesting entity can query a node further by sending a request to the JID and specifying the node of interest in the query.</p>
<example caption='Requesting further nodes'><![CDATA[
<iq type='get'
from='[email protected]/orchard'
to='catalog.shakespeare.lit'
id='items3'>
<query xmlns='http://jabber.org/protocol/disco#items'
node='music'/>
</iq>
]]></example>
<p>The service then returns the further nodes associated with the "parent" node. In the following example, the service itself enforces an alphabetically-ordered hierarchical structure on the nodes that are returned, but such a structure is a matter of implementation rather than protocol.</p>
<example caption='Service returns further nodes'><![CDATA[
<iq type='result'
from='catalog.shakespeare.lit'
to='[email protected]/orchard'
id='items3'>
<query xmlns='http://jabber.org/protocol/disco#items'
node='music'>
<item jid='catalog.shakespeare.lit'
node='music/A'/>
<item jid='catalog.shakespeare.lit'
node='music/B'/>
<item jid='catalog.shakespeare.lit'
node='music/C'/>
<item jid='catalog.shakespeare.lit'
node='music/D'/>
.
.
.
</query>
</iq>
]]></example>
<p>The requesting entity can then query further if desired:</p>
<example caption='Requesting even more nodes'><![CDATA[
<iq type='get'
from='[email protected]/orchard'
to='catalog.shakespeare.lit'
id='items4'>
<query xmlns='http://jabber.org/protocol/disco#items'
node='music/D'/>
</iq>
]]></example>
<example caption='Service returns even more nodes'><![CDATA[
<iq type='result'
from='catalog.shakespeare.lit'
to='[email protected]/orchard'
id='items4'>
<query xmlns='http://jabber.org/protocol/disco#items'
node='music/D'>
<item jid='catalog.shakespeare.lit'
node='music/D/dowland-firstbooke'
name='John Dowland - First Booke of Songes or Ayres'/>
<item jid='catalog.shakespeare.lit'
node='music/D/dowland-solace'
name='John Dowland - A Pilgrimes Solace'/>
</query>
</iq>
]]></example>
</section2>
<section2 topic='Node Hierarchies' anchor='items-hierarchy'>
<p>The foregoing examples show a hierarchy of nodes, in which some nodes are branches (i.e., contain further nodes) and some nodes are leaves (i.e., do not contain further nodes). The "hierarchy" category SHOULD be used to identify such nodes, where the "branch" and "leaf" types are exhaustive of the types within this category.</p>
<p>If the hierarchy category is used, every node in the hierarchy MUST be identified as either a branch or a leaf; however, since a node MAY have multiple identities, any given node MAY also possess an identity other than "hierarchy/branch" or "hierarchy/leaf".</p>
<p>Therefore, a disco#info request to the "music/D" node shown above would yield <identity category='hierarchy' type='branch'/> while a disco#info request to the "music/D/dowland-firstbooke" node would yield <identity category='hierarchy' type='leaf'/> (and each node could yield additional identities as appropriate).</p>
</section2>
<section2 topic='Relationship Between an Entity and its Items' anchor='items-relationship'>
<p>This section explains in greater detail the relationship between an entity and its associated items.</p>
<p>In general, the items returned by an entity in a disco#items result MUST be items over which the entity has some relationship of ownership -- either direct control over the item itself (e.g., <cite>Publish-Subscribe</cite> nodes owned by the entity) or at least the ability to provide or vouch for the item in a canonical way on the Jabber network (e.g., groupchat rooms directly hosted by a multi-user chat service or IRC channels to which a gateway provides access).</p>
<p>Such a relationship does not constrain the relationship between the owning entity's address and the address of the associated entity. In particular, any of the following scenarios is perfectly acceptable:</p>
<ol>
<li><p>Upon querying an entity (JID1) for items, one receives a list of items that can be addressed as JIDs; each associated item has its own JID, but no such JID equals JID1.</p></li>
<li><p>Upon querying an entity (JID1) for items, one receives a list of items that cannot be addressed as JIDs; each associated item has its own JID+node, where each JID equals JID1 and each NodeID is unique.</p></li>
<li><p>Upon querying an entity (JID1+NodeID1) for items, one receives a list of items that can be addressed as JIDs; each associated item has its own JID, but no such JID equals JID1.</p></li>
<li><p>Upon querying an entity (JID1+NodeID1) for items, one receives a list of items that cannot be addressed as JIDs; each associated item has its own JID+node, but no such JID+node equals JID1+NodeID1 and each NodeID is unique in the context of the associated JID.</p></li>
</ol>
<p>In addition, the results MAY also be mixed, so that a query to a JID or a JID+node could yield both (1) items that are addressed as JIDs and (2) items that are addressed as JID+node combinations.</p>
<p>Consider the case of an entity that owns multiple publish-subscribe nodes -- for example, a person who owns one such node for each of his music players. The following examples show what the disco#items query and result might look like (using the protocol defined in &xep0118;):</p>
<example caption='User queries entity regarding tunes'><![CDATA[
<iq from='[email protected]/chamber'
id='items4'
to='[email protected]'
type='get'>
<query xmlns='http://jabber.org/protocol/disco#items'
node='http://jabber.org/protocol/tune'/>
</iq>
]]></example>
<p>The queried entity now returns a list of publish-subscribe nodes over which it has control, each of which is hosted on a different pubsub service:</p>
<example caption='Entity returns multiple items'><![CDATA[
<iq from='[email protected]'
id='items4'
to='[email protected]/chamber'
type='result'>
<query xmlns='http://jabber.org/protocol/disco#items'
node='http://jabber.org/protocol/tune'>
<item jid='pubsub.shakespeare.lit'
name='Romeo's CD player'
node='s623nms9s3bfh8js'/>
<item jid='pubsub.montague.net'
node='music/R/Romeo/iPod'/>
<item jid='tunes.characters.lit'
node='g8k4kds9sd89djf3'/>
</query>
</iq>
]]></example>
</section2>
</section1>
<section1 topic='Publishing Available Items' anchor='publish'>
<p>This feature has been removed in favor of the XMPP publish-subscribe technology defined in &xep0060;.</p>
</section1>
<section1 topic='Implementation Notes' anchor='impl'>
<section2 topic='Number of Info Requests' anchor='impl-info'>
<p>When the requesting application is a client, it may want to retrieve service discovery information about all of a user's contacts after retrieving the user's roster and receiving presence from contacts in the user's roster (e.g., to show capabilities). Unfortunately, a user's roster can be quite large, resulting in sending a large number of outbound disco#info requests and receiving a large number of inbound disco#info responses upon login. Because this "disco flood" is undesirable for reasons of scalability and bandwidth usage, client applications SHOULD use &xep0115; to determine the capabilities of entities from which they receive presence information and SHOULD NOT send disco#info requests to such entities.</p>
</section2>
<section2 topic='Number of Items Requests' anchor='impl-items'>
<p>In order to retrieve full information about an entity and its associated items, the requesting application needs to "walk the tree" of items. Naturally, this can result in a large number of requests and responses. The requesting application SHOULD NOT send follow-up requests to all items associated with an entity if the list of such items is long (e.g., more than twenty items). Entities that will routinely host a large number of items (e.g., IRC gateways or NNTP services) SHOULD structure nodes into hierarchies and/or provide more robust searching capabilities, for example via &xep0055;; they SHOULD NOT return extremely large result sets via Service Discovery.</p>
</section2>
<section2 topic='Response Consistency' anchor='impl-consistency'>
<p>This document recommends but does not require that a responding entity must return the same results in response to the same request from different requesting entities (e.g., an entity could return a different list of items or features based on the degree to which it trusts the requesting entity, or based on the known capabilities of the requesting entity). However, the responding entity SHOULD return the same <identity/> element (category+type) to all disco#info requests sent to the same JID+node combination.</p>
</section2>
</section1>
<section1 topic='Error Conditions' anchor='errors'>
<p>If a specific entity (JID or JID+node) does not support the disco namespace, refuses to return disco results to the specific requesting entity, or refuses to return disco results to any requesting entity, it SHOULD return an appropriate error message (such as &unavailable;, &forbidden;, or ¬allowed;, respectively). One example is shown below.</p>
<example caption='JID+node error'><![CDATA[
<iq type='error'
from='mim.shakespeare.lit'
to='[email protected]/orchard'
id='info3'>
<query xmlns='http://jabber.org/protocol/disco#info'
node='http://jabber.org/protocol/commands'/>
<error type='cancel'>
<not-allowed xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
</error>
</iq>
]]></example>
<p>Other error conditions may be appropriate depending on the application.</p>
<p>The following table summarizes the common error conditions that can have special meaning in the context of Service Discovery (for information regarding error condition syntax and semantics, see &xep0086;).</p>
<table caption='Error Conditions'>
<tr>
<th>Condition</th>
<th>Cause</th>
</tr>
<tr>
<td>¬found;</td>
<td>The JID or JID+NodeID of the specified target entity does not exist and that fact can be divulged in accordance with privacy and security considerations and policies.</td>
</tr>
<tr>
<td>&unavailable;</td>
<td>The target entity does not support this protocol, or the specified target entity does not exist but that fact cannot be divulged because of privacy and security considerations.</td>
</tr>
</table>
<p>The other error conditions specified in <cite>XMPP Core</cite> MAY be returned as well (&forbidden;, ¬allowed;, ¬authorized;, etc.), including application-specific conditions.</p>
<p>As noted above, if an entity has no associated items, it MUST return an empty &QUERY; element (rather than an error) in response to a disco#items request.</p>
</section1>
<section1 topic='Security Considerations' anchor='security'>
<p>Certain attacks may be made easier when an entity discloses (via disco#info responses) that it supports particular protocols or features; however, in general, service discovery introduces no new vulnerabilities, since a malicious entity could discover that the responding entity supports such protocols and features by sending requests specific to those protocols rather than by sending service discovery requests.</p>
<p>A responding entity is under no obligation to return the identical service discovery response when replying to service discovery requests received from different requesting entities, and MAY perform authorization checks before responding in order to determine how (or whether) to respond.</p>
<p>A server MUST carefully control access to any functionality that would enable directory harvesting attacks or that would leak information about connected or available resources; this functionality consists of the server's replies to disco#info and disco#items requests sent to bare JIDs (addresses of the form [email protected]) hosted on the server, since the server responds to such requests on behalf of the account. The following rules apply to the handling of service discovery requests sent to bare JIDs:</p>
<ol>
<li>
<p>In response to a disco#info request, the server MUST return a &unavailable; error if one of the following is true:</p>
<ol>
<li>The target entity does not exist (no matter if the request specifies a node or not).</li>
<li>The requesting entity is not authorized to receive presence from the target entity (i.e., via the target having a presence subscription to the requesting entity of type "both" or "from") or is not otherwise trusted (e.g., another server in a trusted network).</li>
</ol>
</li>
<li>
<p>In response to a disco#items request, the server MUST return an empty result set if:</p>
<ol>
<li>The target entity does not exist (no matter if the request specifies a node or not).</li>
<li>The request did not specify a node, the only items are available resources (as defined in &rfc3921;), and the requesting entity is not authorized to receive presence from the target entity (i.e., via the target having a presence subscription to the requesting entity of type "both" or "from") or is not otherwise trusted (e.g., another server in a trusted network). <note>However, the server MAY return items other than available resources (if any).</note></li>
</ol>
</li>
</ol>
</section1>
<section1 topic='IANA Considerations' anchor='iana'>
<p>This document requires no interaction with &IANA;.</p>
</section1>
<section1 topic='XMPP Registrar Considerations' anchor='registrar'>
<section2 topic='Protocol Namespaces' anchor='registrar-protocol'>
<p>The ®ISTRAR; includes the 'http://jabber.org/protocol/disco#info' and 'http://jabber.org/protocol/disco#items' namespaces in its registry of protocol namespaces.</p>
</section2>
<section2 topic='Registries' anchor='registrar-reg'>
<section3 topic='Identity Categories and Types Registry' anchor='registrar-reg-identity'>
<p>The XMPP Registrar maintains a registry of values for the 'category' and 'type' attributes of the <identity/> element in the 'http://jabber.org/protocol/disco#info' namespace; see &DISCOCATEGORIES;.</p>
<section4 topic='Process' anchor='registrar-identity'>
®PROCESS;
<code><![CDATA[
<category>
<name>the name of the category (all lower-case)</name>
<desc>a natural-language description of the category</desc>
<type>
<name>the name of the specific type (all lower-case)</name>
<desc>a natural-language description of the type</desc>
<doc>the document (e.g., XEP) in which this type is specified</doc>
</type>
</category>
]]></code>
<p>The registrant may register more than one category at a time, each contained in a separate <category/> element. The registrant may also register more than one type at a time, each contained in a separate <type/> child element. Registrations of new types within an existing category must include the full XML snippet but should not include the category description (only the name).</p>
</section4>
<section4 topic='Initial Submission' anchor='registrar-reg-identity-init'>
<p>This document defines a "hierarchy" category that contains two and only two types: "branch" and "leaf"; the associated registry submission is as follows:</p>
<code><![CDATA[
<category>
<name>hierarchy</name>
<desc>
An entity that exists in the context of a
service discovery node hierarchy.
</desc>
<type>
<name>branch</name>
<desc>
A "container node" for other entities in a
service discovery node hierarchy.
</desc>
<doc>XEP-0030</doc>
</type>
<type>
<name>leaf</name>
<desc>
A "terminal node" in a service discovery
node hierarchy.
</desc>
<doc>XEP-0030</doc>
</type>
</category>
]]></code>
</section4>
</section3>
<section3 topic='Features Registry' anchor='registrar-reg-features'>
<p>The XMPP Registrar maintains a registry of features for use as values of the 'var' attribute of the <feature/> element in the 'http://jabber.org/protocol/disco#info' namespace; see &DISCOFEATURES;.</p>
<section4 topic='Process' anchor='registrar-reg-features-process'>
®PROCESS;
<code><![CDATA[
<var>
<name>name of feature or namespace</name>
<desc>a natural-language description of the feature</desc>
<doc>the document (e.g., XEP) in which this feature is specified</doc>
</var>
]]></code>
<p>The registrant may register more than one feature at a time, each contained in a separate <feature/> element.</p>
</section4>
</section3>
<section3 topic='Well-Known Nodes' anchor='registrar-reg-nodes'>
<p>A "using protocol" may specify one or more service discovery nodes that have a special and well-defined meaning in the context of that protocol. For the purpose of reserving these node names globally across all Jabber protocols, the XMPP Registrar maintains a registry of well-known service discovery nodes at &NODES;.</p>
<section4 topic='Process' anchor='registrar-reg-nodes-process'>
®PROCESS;
<code><![CDATA[
<node>
<name>the name of the node</name>
<desc>a natural-language description of the node</desc>
<doc>the document (e.g., XEP) in which this node is specified</doc>
</node>
]]></code>
<p>The registrant may register more than one node at a time, each contained in a separate <node/> element.</p>
</section4>
</section3>
</section2>
<section2 topic='URI Query Types' anchor='registrar-querytypes'>
<p>As authorized by &xep0147;, the XMPP Registrar maintains a registry of queries and key-value pairs for use in XMPP URIs (see &QUERYTYPES;).</p>
<p>The "disco" querytype is defined herein for service discovery interactions, with three keys: (1) "node" (the optional node to query), (2) "request" (with values of "info" to retrieve service discovery information and "items" to retrieve service discovery items), and (3) "type" (with values of "get" for IQ-gets and "set" for IQ-sets).</p>
<example caption='Service Discovery Information Request: IRI/URI'><![CDATA[
xmpp:[email protected]?disco;type=get;request=info
]]></example>
<example caption='Service Discovery Information Request: Resulting Stanza'><![CDATA[
<iq to='[email protected]' type='get'>
<query xmlns='http://jabber.org/protocol/disco#info'/>
</iq>
]]></example>
<example caption='Service Discovery Items Request: IRI/URI'><![CDATA[
xmpp:[email protected]?disco;type=get;request=items
]]></example>
<example caption='Service Discovery Items Request: Resulting Stanza'><![CDATA[
<iq to='[email protected]' type='get'>
<query xmlns='http://jabber.org/protocol/disco#items'/>
</iq>
]]></example>
<p>The following submission registers the "disco" querytype.</p>
<code><![CDATA[
<querytype>
<name>disco</name>
<proto>http://jabber.org/protocol/disco</proto>
<desc>enables interaction for the purpose of service discovery</desc>
<doc>XEP-0030</doc>
<keys>
<key>
<name>node</name>
<desc>the (optional) service discovery node</desc>
</key>
<key>
<name>request</name>
<desc>the service discovery request type</desc>
<values>
<value>
<name>info</name>
<desc>a service discovery information (disco#info) request</desc>
</value>
<value>
<name>items</name>
<desc>a service discovery items (disco#items) request</desc>
</value>
</values>
</key>
<key>
<name>type</name>
<desc>the IQ type</desc>
<values>
<value>
<name>get</name>
<desc>an IQ get</desc>
</value>
</values>
</key>
</keys>
</querytype>
]]></code>
</section2>
</section1>
<section1 topic='XML Schemas' anchor='schemas'>
<section2 topic='disco#info' anchor='schemas-info'>
<code><![CDATA[
<?xml version='1.0' encoding='UTF-8' ?>
<xs:schema
xmlns:xs='http://www.w3.org/2001/XMLSchema'
targetNamespace='http://jabber.org/protocol/disco#info'
xmlns='http://jabber.org/protocol/disco#info'
elementFormDefault='qualified'>
<xs:annotation>
<xs:documentation>
The protocol documented by this schema is defined in
XEP-0030: http://www.xmpp.org/extensions/xep-0030.html
</xs:documentation>
</xs:annotation>
<xs:element name='query'>
<xs:complexType>
<xs:sequence minOccurs='0'>
<xs:choice>
<xs:sequence>
<xs:element ref='feature' maxOccurs='unbounded'/>
<xs:element ref='identity'/>
</xs:sequence>
<xs:sequence>
<xs:element ref='identity' maxOccurs='unbounded'/>
<xs:element ref='feature'/>
</xs:sequence>
</xs:choice>
<xs:choice minOccurs='0' maxOccurs='unbounded'>
<xs:element ref='identity'/>
<xs:element ref='feature'/>
</xs:choice>
</xs:sequence>
<xs:attribute name='node' type='xs:string' use='optional'/>
</xs:complexType>
</xs:element>
<xs:element name='identity'>
<xs:complexType>
<xs:simpleContent>
<xs:extension base='empty'>
<xs:attribute name='category' type='nonEmptyString' use='required'/>
<xs:attribute name='name' type='xs:string' use='optional'/>
<xs:attribute name='type' type='nonEmptyString' use='required'/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name='feature'>
<xs:complexType>
<xs:simpleContent>
<xs:extension base='empty'>
<xs:attribute name='var' type='xs:string' use='required'/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:simpleType name='nonEmptyString'>
<xs:restriction base='xs:string'>
<xs:minLength value='1'/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name='empty'>
<xs:restriction base='xs:string'>
<xs:enumeration value=''/>
</xs:restriction>
</xs:simpleType>
</xs:schema>
]]></code>
</section2>
<section2 topic='disco#items' anchor='schemas-items'>
<code><![CDATA[
<?xml version='1.0' encoding='UTF-8' ?>
<xs:schema
xmlns:xs='http://www.w3.org/2001/XMLSchema'
targetNamespace='http://jabber.org/protocol/disco#items'
xmlns='http://jabber.org/protocol/disco#items'
elementFormDefault='qualified'>
<xs:annotation>
<xs:documentation>
The protocol documented by this schema is defined in
XEP-0030: http://www.xmpp.org/extensions/xep-0030.html
</xs:documentation>
</xs:annotation>
<xs:element name='query'>
<xs:complexType>
<xs:sequence minOccurs='0'>
<xs:element ref='item' minOccurs='0' maxOccurs='unbounded'/>
</xs:sequence>
<xs:attribute name='node' type='xs:string' use='optional'/>
</xs:complexType>
</xs:element>
<xs:element name='item'>
<xs:complexType>
<xs:simpleContent>
<xs:extension base='empty'>
<xs:attribute name='jid' type='fullJIDType' use='required'/>
<xs:attribute name='name' type='xs:string' use='optional'/>
<xs:attribute name='node' type='xs:string' use='optional'/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:simpleType name='fullJIDType'>
<xs:restriction base='xs:string'>
<xs:minLength value='8'/>
<xs:maxLength value='3071'/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name='empty'>
<xs:restriction base='xs:string'>
<xs:enumeration value=''/>
</xs:restriction>
</xs:simpleType>
</xs:schema>
]]></code>
</section2>