Merge remote-tracking branch 'origin/0.10'
[platform/upstream/gstreamer.git] / docs / random / wtay / namespaces
1 XML namespaces
2 ==============
3
4 1) requirements
5 ---------------
6
7 GStreamer uses XML to save a complete media pipeline. This
8 opens a lot of possibilities for end user apps, eg: save
9 constructed pipelines for later reuse, send pipelines over
10 the wire to render data elsewhere etc...
11
12 We will also allow the end user app to insert its own tags
13 into the GStreamer generated XML in order to give more
14 context to the elements. An example of such an app would be
15 gsteditor; while the GStreamer core will save the plain 
16 element hierarchy, the editor will insert its own tags into
17 the XML tree to describe the elements positions, the 
18 signals and other project data that might need to be 
19 externalised.
20
21 And inherent problem with XML is that the use and naming of
22 the tags can be done in an arbitrary way. The GStreamer core
23 will, for example, use the 'element' and 'pad' tags to store
24 the element and pad objects. The description and the nesting 
25 of the tags are described in a DTD (document type definition) 
26 or soon with the proposed 'new' standard of the W3C; Schemas.
27
28 We can see obvious problems when a user app (unaware of the
29 core tags) is also trying to use the 'element' tag for its 
30 own purposes. The core might try to load the 'element' tag
31 desscribing the user app data and the user app might get fed
32 with XML data of the GStreamer core.
33
34 In this document we try to describe how we will solve this problem
35 using namespaces.
36
37
38 2) namespaces
39 -------------
40
41 To avoid the tag conflicts we mentioned, the W3C has incorporated 
42 XML namescapes.
43
44 Were a typical XML document without namespaces would look like:
45
46 <?xml version="1.0"?>
47 <GST-Pipeline>
48  <element>
49   <name>bin</name>
50   <children>
51    ...
52   </children>
53  </element>
54 </GST-Pipeline>
55
56 Tha same document with namespaces look like this:
57
58 <?xml version="1.0"?>
59 <gst:GST-Pipeline xmlns:gst="http://gstreamer.net/gst-core/1.0/">
60  <gst:element>
61    <gst:name>bin</gst:name>
62    <gst:children>
63     ...
64    </gst:children>
65  </gst:element>
66 </gst:GST-Pipeline>
67
68 In front of each tag we add, in this case, gst:. gst: is called the
69 namespace of the document and is declared with a statement:
70
71 <... xmlns:gst="http://gstreamer.net/gst-core/1.0/">
72
73 In this case we define a new namespace 'gst:' that is tied to the URL
74 http://gstreamer.net/gst-core/1.0/. This URL is typically based on
75 a domain you control and doesn't have to point to something valid on
76 the internet. Note that the following document is exactly the same
77 as the one mentioned above:
78
79 <?xml version="1.0"?>
80 <core:GST-Pipeline xmlns:core="http://gstreamer.net/gst-core/1.0/">
81  <core:element>
82    <core:name>bin</gst:name>
83    <core:children>
84     ...
85    </core:children>
86  </core:element>
87 </core:GST-Pipeline>
88
89 GStreamer currently uses xmlns:gst="http://gstreamer.net/gst-core/1.0" as
90 the namespace used for saving the core pipeline.
91
92 3) multi-namespace documents
93 ----------------------------
94
95 Suppose we have a user app that wants to insert its own XML tags into
96 the core GStreamer XML pipelines, for the examples sake we will use the
97 editor as an example.  The editor will insert XML tags inside each
98 element that describes the position and size of the element as it was
99 laid out in the editor.
100
101 For the examples sake, the tags that are used to descibe this meta data
102 will also be names 'element' in order to demonstrate the namespaces.
103
104 The editor will use its own namespace, being: 
105 xmlns:editor="http://gstreamer.net/gst-editor/1.0". This namespace is
106 added to the XML documents header and all the elements the editor will
107 save will have this namespace attached to it. Our interleaved XML
108 document might look like this:
109
110 <?xml version="1.0"?>
111 <gst:GST-Pipeline xmlns:gst="http://gstreamer.net/gst-core/1.0/"
112                   xmlns:editor="http://gstreamer.net/gst-editor/1.0/">
113   <gst:element>
114     <gst:name>bin</gst:name>
115     <gst:children>
116       ...
117     </gst:children>
118     <editor:element>
119       <editor:position x="100" y="50"/>
120     </editor:element>
121   </gst:element>
122 </gst:GST-Pipeline>
123
124 As you can see, the namespaces clearly separate the same XML tags
125 'element'. 
126
127
128 4) implementation considerations
129 --------------------------------
130
131 The GStreamer core doesn't know about user apps inserting data into the 
132 XML, it does not look at XML tags not within its namespace when it 
133 performs the parsing of the XML tree. The core, however, must be
134 able to hand over the XML tree to the user app so it can perform the
135 parsing of its tags inside its namespace. We therefore need hooks inside
136 the framework to accomplish this.
137
138 We also need hooks inside the GStreamer core to signal a user app that
139 it can now insert its tags into the XML tree.
140
141 4.1) XML save hooks
142 -------------------
143
144 GstObject has an abstract class method 
145
146   xmlNodePtr (*save_thyself) (GstObject *object, xmlNodePtr parent)
147
148 A real element or pad will implement this function and construct an XML
149 representation of itself with the parent xmlNodePtr as the parent.
150 An element will typically call the save_thyself function of its
151 parent class before saving itself.
152
153 The XML save procedure on a GstObject is performed with:
154
155   gst_object_save_thyself (GstObject *object, xmlNodePtr parent)
156
157 Wich will call the elements implementation of the save_thyself function.
158
159 An app that wants to insert its XML tags has to connect to a signal of
160 the GstObject object called xml_saved. The object and the parent
161 xmlNodePtr will be passed to the signal handler of the user app, which
162 can then insert its tags.
163
164 The user app has no problem inserting its namespace into the xmlDoc and
165 neither will the GStreamer core.
166
167 4.2) XML load hooks
168 -------------------
169
170 The real problem lies in the loading of the XML tree. Before we load
171 the objects, we don't have anything to connect a signal to, so 
172 another method has to be invented to signal the user app of the
173 freshly loaded objects.
174
175 One obvious solution would be to attach a class signal to the 
176 GstObject class that would be fired whenever an object is created from
177 an XML document. Unfortunatly Gtk+ (or glib2.0) doesn't have class
178 signals so we need something else. Another problem with the class 
179 signals would be that the user app would also be notified of object
180 creation outside its context. For example, if two threads perform an 
181 XML load at the same time, the objects created in the first thread
182 would also notify the listener in the second thread. Both threads then
183 have to take care of not trying to parse XML documents that are from 
184 the other thread, this obvously can get messy and we have to deal
185 with it without bothering the user app.
186
187 We'll continue with some random ramblings...
188
189 solution 1
190 ----------
191 To solve this problem we can create a special method in gstobject
192
193 gst_object_loaded_notify_add (GstObjectLoadedCallback *callback,
194                               xmlNodePtr doc)
195
196 this method would add the specified callback function to a list of 
197 listeners and would perform the callback function if an object is 
198 created (this can be done in the init method). The problem remains
199 though because we do not know the xmlNodePtr when we call the 
200 callback. This seems messy.
201
202 sultion 2
203 ---------
204 After the object has performed its restore_thyself, it is responsible
205 for signaling a object_loaded signal with the object and the xmlNodePtr
206 as an argument.
207
208 At object creation, the signal is connected to a singleton object managed
209 by GstObject that can proxy the signal to the user app. This looks a
210 lot like a class signal. apps could also specify the xmlNodePtr they
211 are interested in and the signal would only be proxied to the app
212 if the xmlNodePtrs are from the same xmlDoc.
213
214 Solution 2 seems like a reasonable solution for now...
215
216 comments?
217
218 wtay
219