1XML::Spice(3) User Contributed Perl Documentation XML::Spice(3)
2
3
4
6 XML::Spice - generating XML has never been so Perly!
7
9 use XML::Spice qw(html head title body h1 p a);
10
11 print
12 html(
13 head(
14 title("my great page"),
15 ),
16 body(
17 h1("my great page"),
18 p("this is my great page, made with ",
19 a("spice", { href => "http://en.wikipedia.org/wiki/Spice/" }),
20 ),
21 ),
22 );
23
25 XML::Spice is yet another XML generation module. It tries to take some
26 of the pain out of generating XML by making it more like Perl.
27
28 Unless you've got a really good module for producing XML for your
29 particular use (like a module for interfacing with a specific web
30 service), you've probably found that you end up resorting to code like
31 this:
32
33 my $xml = q{<foo><bar><baz /></bar><quux /></foo>};
34
35 Of course this works great, and you can't beat it for speed, but it
36 quickly becomes difficult to work with. Your syntax highlighting
37 probably just displays it as a giant string. You can't easily see
38 mismatched brackets or other bugs until your code runs and tries to
39 parse the thing. And, once you start adding attributes and character
40 data into the mix, it rapidly moves towards being impossible to read.
41
42 Instead of this, you could use XML::Spice and write the same thing in
43 Perl:
44
45 my $xml = foo(bar(baz()), quux());
46
47 You'll can add liberal amounts of whitespace to convey structure
48 without it making your output larger. You get Perl checking to make
49 sure that you haven't left anything out. You can use all the power of
50 Perl to generate and include data without having to pepper your code
51 with interpolated strings or concatenation operators. And you get a
52 guarantee that the XML produced is valid.
53
55 If you "use" (or "import") XML::Spice without any arguments, it will
56 export a single function "x()" into your package. This is the only real
57 function in XML::Spice, and its used to implement everything else.
58
59 "x()" generates a single element, which in turn can contain attributes,
60 character data, sub-elements (via additional calls to "x()"), and more.
61 The general format for "x()" is:
62
63 my $xml = x("element", ...);
64
65 The first argument is required, and is always the name of the element
66 to generate. So "x("foo")" produces "<foo/>".
67
68 Generally though, you'll want to use the more readable named functions
69 to do the work. You get these by providing arguments to XML::Spice when
70 you "use" it (or call "import"). For example:
71
72 use XML::Spice qw(foo bar baz);
73
74 This will export three functions into your package, "foo()", "bar()"
75 and "baz()", and won't import "x()". Calling these functions produces
76 the same results as calling "x()" with the name as the first argument,
77 that is:
78
79 my $xml = foo(...);
80
81 produces identical results to:
82
83 my $xml = x("foo", ...);
84
85 "x()" returns an "XML::Spice::Chunk" object, which when stringified (ie
86 "print"ed or interpolated into a string) produces the XML of its input.
87 Generally you won't care, you'll just stringify it and be done with it.
88 There are however some rather clever things that can be done by having
89 the return value be an object instead of a normal string; see "ADVANCED
90 USAGE" for details.
91
93 "x()" can take zero or more additional arguments. These arguments
94 define what else gets added to the element. What happens depends on
95 what you pass.
96
97 attributes
98 Attributes are added to the element by passing a hash reference,
99 eg:
100
101 img({ src => "hello.jpg" });
102
103 produces:
104
105 <img src='hello.jpg' />
106
107 If you pass multiple hash references, their contents are combined,
108 with the value from the last hash passed being used in the case of
109 a conflict.
110
111 sub-elements
112 Sub-elements are included in an element by passing the output from
113 another call to "x()", eg:
114
115 foo(bar());
116
117 produces:
118
119 <foo><bar /></foo>
120
121 character data
122 Character data is added to the element by passing simple strings,
123 eg:
124
125 p("this is my paragraph");
126
127 produces:
128
129 <p>this is my paragraph</p>
130
131 These arguments can be mixed as much as you like, eg:
132
133 p("Visit my ", a({ href => "http://homepage.com/"}, "homepage"), " for more information.");
134
135 produces:
136
137 <p>Visit my <a href='http://homepage.com/'>homepage</a> for more information.</p>
138
139 Other things can be passed to "x()"; those are described in "ADVANCED
140 USAGE".
141
143 Dynamic tree generation
144 The most important thing to understand about the "XML::Spice::Chunk"
145 objects returned by "x()" is that they do nothing until they are
146 stringified to produce XML output. This makes it possible to pass code
147 references or even other objects to "x()" and have them dynamically
148 generate data to be included in the produced XML.
149
150 If a code reference is passed to "x()", it is called when the resultant
151 "XML::Spice::Chunk" is stringified and its output is included at the
152 position that the code reference was at, eg:
153
154 p("the time is ", sub { scalar localtime });
155
156 would produce something like:
157
158 <p>the time is Sat Sep 26 22:32:57 2009</p>
159
160 "XML::Spice::Chunk" will recursively evaluate the result from the code
161 reference until it gets down to basic strings and hash references as
162 described in "BASIC USAGE". This is great for producing lists of
163 things, eg:
164
165 my $list = ul(sub {
166 my @results;
167 opendir my $dir, "images";
168 push @results, li($_) for grep { m/\.png$/ } readdir $dir;
169 closedir $dir;
170 return @results;
171 });
172
173 When $list is stringified, the sub will be called and would return a
174 list of "XML::Spice::Chunk" objects. These in turn will be stringified
175 until eventually only strings are left and output like the following is
176 produced:
177
178 <ul><li>foo.png</li><li>bar.png</li><li>baz.png</li></ul>
179
180 Had the sub itself returned a code reference, then that in turn would
181 have been called and its output used.
182
183 The code reference is called every time the "XML::Spice::Chunk" object
184 is stringified. If the computed result will not change, consider
185 caching the result.
186
187 To support this, the following things may be passed to "x()" (and thus
188 returned by code references or objects):
189
190 undef
191 If "undef" is passed to "x()", it is ignored. That is:
192
193 foo("bar", undef, "baz");
194
195 is exactly equivalent to:
196
197 foo("bar", "baz");
198
199 and produces:
200
201 <foo>barbaz</foo>
202
203 array reference
204 If an array reference is passed to "x()", it is flattened. That is:
205
206 foo("bar", [ baz(), "quux" ]);
207
208 is exactly equivalent to:
209
210 foo("bar", baz(), "quux");
211
212 and produces:
213
214 <foo>bar<baz />quux</foo>
215
216 Result cache
217 A chunk is only evaluated the first time it is stringified. The result
218 is cached and each subsequent stringification will return the cached
219 result. If you wanted to reuse a chunk (eg if it has a coderef in it
220 that does a database lookup), you can call its "forget()" method to
221 remove the cached result. The next time it is stringified it will be
222 reevaluated from scratch.
223
225 "XML::Spice" can produce pretty-printed output. Because the additional
226 whitespace subtly changes the semantics of the generated XML this is
227 only intended as a debugging feature. This also disables the result
228 cache.
229
230 To use it, you'll need the XML::Tidy::Tiny module installed. Then to
231 enable it, set (and localise!) $XML::Spice::PRETTY_PRINT to a true
232 value before stringifying a chunk.
233
235 Optimised namespace declarations
236 If two sub-chunks declare the same namespace, then move the
237 declaration to the parent chunk.
238
240 This module guarantees that the XML it produces will be valid and
241 semantically equivalent to the input you give it, but it makes no
242 guarantees and gives no control over things like use of entity encoding
243 vs. CDATA sections, declaration of namespaces and use of prefixes, and
244 so forth. The method used may change between releases, producing
245 different results. If you require exact control over the details of the
246 XML produced, then this module is not for you.
247
249 Bugs / Feature Requests
250 Please report any bugs or feature requests through the issue tracker at
251 <https://github.com/robn/XML-Spice/issues>. You will be notified
252 automatically of any progress on your issue.
253
254 Source Code
255 This is open source software. The code repository is available for
256 public review and contribution under the terms of the license.
257
258 <https://github.com/robn/XML-Spice>
259
260 git clone https://github.com/robn/XML-Spice.git
261
263 ยท Robert Norris <rob@eatenbyagrue.org>
264
266 This software is copyright (c) 2006-2016 by Robert Norris.
267
268 This is free software; you can redistribute it and/or modify it under
269 the same terms as the Perl 5 programming language system itself.
270
271
272
273perl v5.32.0 2020-07-28 XML::Spice(3)