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() and
75 baz(), and won't import x(). Calling these functions produces the same
76 results as calling x() with the name as the first argument, that is:
77
78 my $xml = foo(...);
79
80 produces identical results to:
81
82 my $xml = x("foo", ...);
83
84 x() returns an "XML::Spice::Chunk" object, which when stringified (ie
85 "print"ed or interpolated into a string) produces the XML of its input.
86 Generally you won't care, you'll just stringify it and be done with it.
87 There are however some rather clever things that can be done by having
88 the return value be an object instead of a normal string; see "ADVANCED
89 USAGE" for details.
90
92 x() can take zero or more additional arguments. These arguments define
93 what else gets added to the element. What happens depends on what you
94 pass.
95
96 attributes
97 Attributes are added to the element by passing a hash reference,
98 eg:
99
100 img({ src => "hello.jpg" });
101
102 produces:
103
104 <img src='hello.jpg' />
105
106 If you pass multiple hash references, their contents are combined,
107 with the value from the last hash passed being used in the case of
108 a conflict.
109
110 sub-elements
111 Sub-elements are included in an element by passing the output from
112 another call to x(), eg:
113
114 foo(bar());
115
116 produces:
117
118 <foo><bar /></foo>
119
120 character data
121 Character data is added to the element by passing simple strings,
122 eg:
123
124 p("this is my paragraph");
125
126 produces:
127
128 <p>this is my paragraph</p>
129
130 These arguments can be mixed as much as you like, eg:
131
132 p("Visit my ", a({ href => "http://homepage.com/"}, "homepage"), " for more information.");
133
134 produces:
135
136 <p>Visit my <a href='http://homepage.com/'>homepage</a> for more information.</p>
137
138 Other things can be passed to x(); those are described in "ADVANCED
139 USAGE".
140
142 Dynamic tree generation
143 The most important thing to understand about the "XML::Spice::Chunk"
144 objects returned by x() is that they do nothing until they are
145 stringified to produce XML output. This makes it possible to pass code
146 references or even other objects to x() and have them dynamically
147 generate data to be included in the produced XML.
148
149 If a code reference is passed to x(), it is called when the resultant
150 "XML::Spice::Chunk" is stringified and its output is included at the
151 position that the code reference was at, eg:
152
153 p("the time is ", sub { scalar localtime });
154
155 would produce something like:
156
157 <p>the time is Sat Sep 26 22:32:57 2009</p>
158
159 "XML::Spice::Chunk" will recursively evaluate the result from the code
160 reference until it gets down to basic strings and hash references as
161 described in "BASIC USAGE". This is great for producing lists of
162 things, eg:
163
164 my $list = ul(sub {
165 my @results;
166 opendir my $dir, "images";
167 push @results, li($_) for grep { m/\.png$/ } readdir $dir;
168 closedir $dir;
169 return @results;
170 });
171
172 When $list is stringified, the sub will be called and would return a
173 list of "XML::Spice::Chunk" objects. These in turn will be stringified
174 until eventually only strings are left and output like the following is
175 produced:
176
177 <ul><li>foo.png</li><li>bar.png</li><li>baz.png</li></ul>
178
179 Had the sub itself returned a code reference, then that in turn would
180 have been called and its output used.
181
182 The code reference is called every time the "XML::Spice::Chunk" object
183 is stringified. If the computed result will not change, consider
184 caching the result.
185
186 To support this, the following things may be passed to x() (and thus
187 returned by code references or objects):
188
189 undef
190 If "undef" is passed to x(), it is ignored. That is:
191
192 foo("bar", undef, "baz");
193
194 is exactly equivalent to:
195
196 foo("bar", "baz");
197
198 and produces:
199
200 <foo>barbaz</foo>
201
202 array reference
203 If an array reference is passed to x(), it is flattened. That is:
204
205 foo("bar", [ baz(), "quux" ]);
206
207 is exactly equivalent to:
208
209 foo("bar", baz(), "quux");
210
211 and produces:
212
213 <foo>bar<baz />quux</foo>
214
215 Result cache
216 A chunk is only evaluated the first time it is stringified. The result
217 is cached and each subsequent stringification will return the cached
218 result. If you wanted to reuse a chunk (eg if it has a coderef in it
219 that does a database lookup), you can call its forget() method to
220 remove the cached result. The next time it is stringified it will be
221 reevaluated from scratch.
222
224 "XML::Spice" can produce pretty-printed output. Because the additional
225 whitespace subtly changes the semantics of the generated XML this is
226 only intended as a debugging feature. This also disables the result
227 cache.
228
229 To use it, you'll need the XML::Tidy::Tiny module installed. Then to
230 enable it, set (and localise!) $XML::Spice::PRETTY_PRINT to a true
231 value before stringifying a chunk.
232
234 Optimised namespace declarations
235 If two sub-chunks declare the same namespace, then move the
236 declaration to the parent chunk.
237
239 This module guarantees that the XML it produces will be valid and
240 semantically equivalent to the input you give it, but it makes no
241 guarantees and gives no control over things like use of entity encoding
242 vs. CDATA sections, declaration of namespaces and use of prefixes, and
243 so forth. The method used may change between releases, producing
244 different results. If you require exact control over the details of the
245 XML produced, then this module is not for you.
246
248 Bugs / Feature Requests
249 Please report any bugs or feature requests through the issue tracker at
250 <https://github.com/robn/XML-Spice/issues>. You will be notified
251 automatically of any progress on your issue.
252
253 Source Code
254 This is open source software. The code repository is available for
255 public review and contribution under the terms of the license.
256
257 <https://github.com/robn/XML-Spice>
258
259 git clone https://github.com/robn/XML-Spice.git
260
262 • Robert Norris <rob@eatenbyagrue.org>
263
265 This software is copyright (c) 2006-2016 by Robert Norris.
266
267 This is free software; you can redistribute it and/or modify it under
268 the same terms as the Perl 5 programming language system itself.
269
270
271
272perl v5.38.0 2023-07-21 XML::Spice(3)