-
Notifications
You must be signed in to change notification settings - Fork 0
/
HandlingXML.html
207 lines (162 loc) · 15.4 KB
/
HandlingXML.html
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
<!DOCTYPE html>
<html lang="en" data-content_root="./">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Handling XML</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css?v=fa44fd50" />
<link rel="stylesheet" type="text/css" href="_static/bootstrap-sphinx.css?v=fadd4351" />
<link rel="stylesheet" type="text/css" href="_static/custom.css?v=77160d70" />
<script src="_static/documentation_options.js?v=a8da1a53"></script>
<script src="_static/doctools.js?v=9bcbadda"></script>
<script src="_static/sphinx_highlight.js?v=dc90522c"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="next" title="Index Property" href="IndexProperty.html" />
<link rel="prev" title="Event Workspace Development" href="EventWorkspaceDev.html" />
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-59110517-1', 'auto');
ga('send', 'pageview');
</script>
</head><body>
<div id="navbar" class="navbar navbar-default ">
<div class="container">
<div class="navbar-header">
<!-- .btn-navbar is used as the toggle for collapsed navbar content -->
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".nav-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="http://www.mantidproject.org">
</a>
<span class="navbar-text navbar-version pull-left"><b>main</b></span>
</div>
<div class="collapse navbar-collapse nav-collapse">
<ul class="nav navbar-nav">
<li class="divider-vertical"></li>
<li><a href="index.html">Home</a></li>
<li><a href="https://download.mantidproject.org">Download</a></li>
<li><a href="https://docs.mantidproject.org">User Documentation</a></li>
<li><a href="http://www.mantidproject.org/contact">Contact Us</a></li>
</ul>
<form class="navbar-form navbar-right" action="search.html" method="get">
<div class="form-group">
<input type="text" name="q" class="form-control" placeholder="Search" />
</div>
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<p>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="nav-item nav-item-0"><a href="index.html">Documentation</a> »</li>
<li class="nav-item nav-item-this"><a href="">Handling XML</a></li>
</ul>
</div> </p>
</div>
<div class="container">
<div class="row">
<div class="body col-md-12 content" role="main">
<section id="handling-xml">
<h1>Handling XML<a class="headerlink" href="#handling-xml" title="Link to this heading">¶</a></h1>
<p>This page provides an introduction into reading/writing XML effectively
within Mantid. In Mantid, we use Poco to handling XML serialisation. A
useful introductory presentation can be found <a class="reference external" href="http://pocoproject.org/slides/170-XML.pdf">here.</a></p>
<p><strong>This page is a work in progress.</strong></p>
<section id="examples">
<h2>Examples<a class="headerlink" href="#examples" title="Link to this heading">¶</a></h2>
<section id="parsing">
<h3>Parsing<a class="headerlink" href="#parsing" title="Link to this heading">¶</a></h3>
<div class="highlight-cpp notranslate"><div class="highlight"><pre><span></span><span class="cp">#include</span><span class="w"> </span><span class="cpf"><Poco/DOM/Document.h></span>
<span class="cp">#include</span><span class="w"> </span><span class="cpf"><Poco/DOM/DOMParser.h></span>
<span class="cp">#include</span><span class="w"> </span><span class="cpf"><Poco/DOM/Element.h></span>
<span class="n">Poco</span><span class="o">::</span><span class="n">XML</span><span class="o">::</span><span class="n">DOMParser</span><span class="w"> </span><span class="n">pParser</span><span class="p">;</span>
<span class="n">Poco</span><span class="o">::</span><span class="n">AutoPtr</span><span class="o"><</span><span class="n">Poco</span><span class="o">::</span><span class="n">XML</span><span class="o">::</span><span class="n">Document</span><span class="o">></span><span class="w"> </span><span class="n">pDoc</span><span class="p">;</span>
<span class="k">try</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">pDoc</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">pParser</span><span class="p">.</span><span class="n">parseString</span><span class="p">(</span><span class="n">cuboidStr</span><span class="p">);</span>
<span class="p">}</span><span class="w"> </span><span class="k">catch</span><span class="w"> </span><span class="p">(...)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="c1">// Handle the failure as appropriate</span>
<span class="p">}</span>
<span class="c1">// Get pointer to root element</span>
<span class="n">Poco</span><span class="o">::</span><span class="n">XML</span><span class="o">::</span><span class="n">Element</span><span class="w"> </span><span class="o">*</span><span class="n">pRootElem</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">pDoc</span><span class="o">-></span><span class="n">documentElement</span><span class="p">();</span>
</pre></div>
</div>
</section>
<section id="iterating-over-an-element-s-children">
<h3>Iterating over an element’s children<a class="headerlink" href="#iterating-over-an-element-s-children" title="Link to this heading">¶</a></h3>
<div class="highlight-cpp notranslate"><div class="highlight"><pre><span></span><span class="n">Poco</span><span class="o">::</span><span class="n">XML</span><span class="o">::</span><span class="n">Element</span><span class="w"> </span><span class="o">*</span><span class="n">pRootElem</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">pDoc</span><span class="o">-></span><span class="n">documentElement</span><span class="p">();</span>
<span class="c1">//Iterate over every child node (non-recursively)</span>
<span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="n">Node</span><span class="w"> </span><span class="o">*</span><span class="n">pNode</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">pRootElem</span><span class="o">-></span><span class="n">firstChild</span><span class="p">();</span><span class="w"> </span><span class="n">pNode</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span><span class="w"> </span><span class="n">pNode</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">pNode</span><span class="o">-></span><span class="n">nextSibling</span><span class="p">())</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">auto</span><span class="w"> </span><span class="n">pElem</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">dynamic_cast</span><span class="o"><</span><span class="n">Poco</span><span class="o">::</span><span class="n">XML</span><span class="o">::</span><span class="n">Element</span><span class="o">*></span><span class="p">(</span><span class="n">pNode</span><span class="p">);</span>
<span class="w"> </span><span class="k">if</span><span class="p">(</span><span class="n">pElem</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="c1">//We can now do something with this element safely</span>
<span class="w"> </span><span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
</section>
<section id="inspecting-an-element">
<h3>Inspecting an element<a class="headerlink" href="#inspecting-an-element" title="Link to this heading">¶</a></h3>
<div class="highlight-cpp notranslate"><div class="highlight"><pre><span></span><span class="n">Poco</span><span class="o">::</span><span class="n">XML</span><span class="o">::</span><span class="n">Element</span><span class="w"> </span><span class="o">*</span><span class="n">pElem</span><span class="p">;</span>
<span class="c1">//Reasonably quick operations</span>
<span class="k">const</span><span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="w"> </span><span class="n">tag</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">pElem</span><span class="o">-></span><span class="n">tagName</span><span class="p">();</span><span class="w"> </span><span class="c1">//for <foo>bar</foo> the tag is 'foo'</span>
<span class="k">const</span><span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="w"> </span><span class="n">value</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">pElem</span><span class="o">-></span><span class="n">innerText</span><span class="p">();</span><span class="w"> </span><span class="c1">//for the above example: 'bar'</span>
<span class="n">Poco</span><span class="o">::</span><span class="n">XML</span><span class="o">::</span><span class="n">Node</span><span class="w"> </span><span class="o">*</span><span class="n">pNext</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">pElem</span><span class="o">-></span><span class="n">nextSibling</span><span class="p">();</span>
<span class="n">Poco</span><span class="o">::</span><span class="n">XML</span><span class="o">::</span><span class="n">Node</span><span class="w"> </span><span class="o">*</span><span class="n">pPrev</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">pElem</span><span class="o">-></span><span class="n">previousSibling</span><span class="p">();</span>
<span class="n">Poco</span><span class="o">::</span><span class="n">XML</span><span class="o">::</span><span class="n">Node</span><span class="w"> </span><span class="o">*</span><span class="n">pChild</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">pElem</span><span class="o">-></span><span class="n">firstChild</span><span class="p">();</span><span class="w"> </span><span class="c1">//avoid lastChild, it's expensive</span>
</pre></div>
</div>
</section>
</section>
<section id="avoid-nodelist">
<h2>Avoid NodeList<a class="headerlink" href="#avoid-nodelist" title="Link to this heading">¶</a></h2>
<p>There are numerous functions that return a <code class="docutils literal notranslate"><span class="pre">Poco::XML::NodeList</span></code>. You
should avoid using them and the list they return as best you can.</p>
<p>NodeList is a very inefficient container. Its <code class="docutils literal notranslate"><span class="pre">item</span></code> method has a cost
equivalent to the value of <code class="docutils literal notranslate"><span class="pre">i</span></code> given to it, and its <code class="docutils literal notranslate"><span class="pre">length</span></code> method
a cost of <code class="docutils literal notranslate"><span class="pre">n</span></code>, where <code class="docutils literal notranslate"><span class="pre">n</span></code> is the number of nodes in the list.</p>
<p>This means that running the following is horrendously slow:</p>
<div class="highlight-cpp notranslate"><div class="highlight"><pre><span></span><span class="c1">// NEVER DO THIS</span>
<span class="n">Poco</span><span class="o">::</span><span class="n">AutoPtr</span><span class="o"><</span><span class="n">Poco</span><span class="o">::</span><span class="n">XML</span><span class="o">::</span><span class="n">NodeList</span><span class="o">></span><span class="w"> </span><span class="n">pElems</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">pElem</span><span class="o">-></span><span class="n">getElementsByTagName</span><span class="p">(</span><span class="s">"foo"</span><span class="p">);</span>
<span class="k">for</span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o"><</span><span class="w"> </span><span class="n">pElems</span><span class="o">-></span><span class="n">length</span><span class="p">();</span><span class="w"> </span><span class="o">++</span><span class="n">i</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="c1">// length costs N, and is called N times (N² cost)</span>
<span class="w"> </span><span class="n">Poco</span><span class="o">::</span><span class="n">XML</span><span class="o">::</span><span class="n">Node</span><span class="o">*</span><span class="w"> </span><span class="n">pNode</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">pElems</span><span class="o">-></span><span class="n">item</span><span class="p">(</span><span class="n">i</span><span class="p">);</span><span class="w"> </span><span class="c1">// item costs at least i and is called N times, with i from 0 -> N-1 (N² + N cost)</span>
<span class="p">}</span>
<span class="c1">// NEVER DO THIS</span>
</pre></div>
</div>
<p>Even if the compiler is smart enough to optimise <code class="docutils literal notranslate"><span class="pre">pElems->length()</span></code> to
a single call, we still have N² + N performance at best. Instead, we
should <strong>always</strong> use the iteration example given earlier, as that runs
in N time, instead of N².</p>
</section>
</section>
</div>
</div>
</div>
<footer class="footer">
<div class="container">
<ul class="nav navbar-nav" style=" float: right;">
<li>
<a href="EventWorkspaceDev.html" title="Previous Chapter: Event Workspace Development"><span class="glyphicon glyphicon-chevron-left visible-sm"></span><span class="hidden-sm hidden-tablet">« Event Workspa...</span>
</a>
</li>
<li>
<a href="IndexProperty.html" title="Next Chapter: Index Property"><span class="glyphicon glyphicon-chevron-right visible-sm"></span><span class="hidden-sm hidden-tablet">Index Property »</span>
</a>
</li>
<li><a href="#">Back to top</a></li>
</ul>
<p>
</p>
</div>
</footer>
</body>
</html>