xml_to_json 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,2 @@
1
+ <?xml-stylesheet type="text/xsl" href="xml2js.xslt"?>
2
+ <root>This is a test</root>
@@ -0,0 +1,49 @@
1
+ <?xml-stylesheet type="text/xsl" href="xml2json.xslt"?>
2
+ <!--
3
+ Test XML markup for converting xml to JSON using XSLT.
4
+ By Doeke Zanstra, 2006
5
+ -->
6
+ <root version="1.0" xmlns:ding="http://zanstra.com/ding">
7
+ this text should be ignored
8
+ <positive>123</positive>
9
+ <negative>-12</negative>
10
+ <zero>0</zero>
11
+ <fixed>10.25</fixed>
12
+ <fixed-neg>-10.25</fixed-neg>
13
+ <padded_zero>01</padded_zero>
14
+ <ding:dong-dang.dung>Namespaced element with dash and dot</ding:dong-dang.dung>
15
+ <yo123-ho456/>
16
+ <string>Zooi</string>
17
+ <string>Tab Text</string>
18
+ <string>Quote "test"</string>
19
+ <string>Backslash \ test</string>
20
+ <string>Quote " en \ test</string>
21
+ <string>"Begin/end quote"</string>
22
+ <escape>Line one (één in Dutch)
23
+ Line two: tab
24
+ He said: "Much fun with a €"
25
+ More unicode&#8224;</escape>
26
+ <int>123</int>
27
+ <float>-12.123</float>
28
+ <exp>-1.234e5</exp>
29
+ <boolean>true</boolean>
30
+ <nil/>
31
+ <empty></empty>
32
+ <object test="true" attributes="are commented">
33
+ <zooi>jaja</zooi>
34
+ <zut>frot</zut>
35
+ </object>
36
+ <array>
37
+ <item/>
38
+ <item>true</item>
39
+ <item>2</item>
40
+ <item>3</item>
41
+ <item>4</item>
42
+ <item>5</item>
43
+ <item>six</item>
44
+ <item>
45
+ <key>item</key>
46
+ <value>7</value>
47
+ </item>
48
+ </array>
49
+ </root>
@@ -0,0 +1,2 @@
1
+ <?xml-stylesheet type="text/xsl" href="xml2js.xslt"?>
2
+ <root>This is a test</root>
@@ -0,0 +1,360 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
3
+ <!--
4
+ Copyright (c) 2006, Doeke Zanstra
5
+ All rights reserved.
6
+
7
+ Redistribution and use in source and binary forms, with or without modification,
8
+ are permitted provided that the following conditions are met:
9
+
10
+ Redistributions of source code must retain the above copyright notice, this
11
+ list of conditions and the following disclaimer. Redistributions in binary
12
+ form must reproduce the above copyright notice, this list of conditions and the
13
+ following disclaimer in the documentation and/or other materials provided with
14
+ the distribution.
15
+
16
+ Neither the name of the dzLib nor the names of its contributors may be used to
17
+ endorse or promote products derived from this software without specific prior
18
+ written permission.
19
+
20
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
21
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23
+ IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
24
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
25
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
29
+ THE POSSIBILITY OF SUCH DAMAGE.
30
+ -->
31
+
32
+ <xsl:output indent="no" omit-xml-declaration="yes" method="text" encoding="UTF-8" media-type="text/javascript"/>
33
+ <xsl:strip-space elements="*"/>
34
+
35
+ <!-- ignore document text -->
36
+ <xsl:template match="text()[preceding-sibling::node() or following-sibling::node()]"/>
37
+
38
+ <!-- JS: ignore attributes (convert to comment) -->
39
+ <xsl:template name="attrs">
40
+ <xsl:if test="not(count(attribute::*)=0)">
41
+ <xsl:text>/*</xsl:text>
42
+ <xsl:for-each select="attribute::*">
43
+ <xsl:text>@</xsl:text>
44
+ <xsl:value-of select="local-name()"/>
45
+ <xsl:text>="</xsl:text>
46
+ <xsl:value-of select="."/>
47
+ <xsl:text>"</xsl:text>
48
+ <xsl:if test="not(position()=last() or last()=1)">
49
+ <xsl:text> </xsl:text>
50
+ </xsl:if>
51
+ </xsl:for-each>
52
+ <xsl:text>*/</xsl:text>
53
+ </xsl:if>
54
+ </xsl:template>
55
+
56
+ <!-- string -->
57
+ <xsl:template match="text()">
58
+ <xsl:call-template name="escape-string">
59
+ <xsl:with-param name="s" select="."/>
60
+ </xsl:call-template>
61
+ </xsl:template>
62
+
63
+ <!-- Main template for escaping strings; used by above template and for object-properties
64
+ Responsibilities: placed quotes around string, and chain up to next filter, escape-bs-string -->
65
+ <xsl:template name="escape-string">
66
+ <xsl:param name="s"/>
67
+ <xsl:text>"</xsl:text>
68
+ <xsl:call-template name="escape-bs-string">
69
+ <xsl:with-param name="s" select="$s"/>
70
+ </xsl:call-template>
71
+ <xsl:text>"</xsl:text>
72
+ </xsl:template>
73
+
74
+ <!-- Escape the backslash (\) before everything else. -->
75
+ <xsl:template name="escape-bs-string">
76
+ <xsl:param name="s"/>
77
+ <xsl:choose>
78
+ <xsl:when test="contains($s,'\')">
79
+ <xsl:call-template name="escape-quot-string">
80
+ <xsl:with-param name="s" select="concat(substring-before($s,'\'),'\\')"/>
81
+ </xsl:call-template>
82
+ <xsl:call-template name="escape-bs-string">
83
+ <xsl:with-param name="s" select="substring-after($s,'\')"/>
84
+ </xsl:call-template>
85
+ </xsl:when>
86
+ <xsl:otherwise>
87
+ <xsl:call-template name="escape-quot-string">
88
+ <xsl:with-param name="s" select="$s"/>
89
+ </xsl:call-template>
90
+ </xsl:otherwise>
91
+ </xsl:choose>
92
+ </xsl:template>
93
+
94
+ <!-- Escape the double quote ("). -->
95
+ <xsl:template name="escape-quot-string">
96
+ <xsl:param name="s"/>
97
+ <xsl:choose>
98
+ <xsl:when test="contains($s,'&quot;')">
99
+ <xsl:call-template name="encode-string">
100
+ <xsl:with-param name="s" select="concat(substring-before($s,'&quot;'),'\&quot;')"/>
101
+ </xsl:call-template>
102
+ <xsl:call-template name="escape-quot-string">
103
+ <xsl:with-param name="s" select="substring-after($s,'&quot;')"/>
104
+ </xsl:call-template>
105
+ </xsl:when>
106
+ <xsl:otherwise>
107
+ <xsl:call-template name="encode-string">
108
+ <xsl:with-param name="s" select="$s"/>
109
+ </xsl:call-template>
110
+ </xsl:otherwise>
111
+ </xsl:choose>
112
+ </xsl:template>
113
+
114
+ <!-- JS: old version of template, doing the same as escape-bs-string and escape-quot-string together, only more complicated -->
115
+ <xsl:template name="escape-bs-and-quot-string-in-one-template">
116
+ <xsl:param name="s"/>
117
+ <!-- First handle -->
118
+ <xsl:choose>
119
+ <!-- double quote -->
120
+ <xsl:when test="contains($s,'&quot;') and not(contains($s,'\'))">
121
+ <xsl:call-template name="encode-string">
122
+ <xsl:with-param name="s" select="substring-before($s,'&quot;')"/>
123
+ </xsl:call-template>
124
+ <xsl:text>\"</xsl:text>
125
+ <xsl:call-template name="escape-string">
126
+ <xsl:with-param name="s" select="substring-after($s,'&quot;')"/>
127
+ </xsl:call-template>
128
+ </xsl:when>
129
+ <!-- backslash -->
130
+ <xsl:when test="not(contains($s,'&quot;')) and contains($s,'\')">
131
+ <xsl:call-template name="encode-string">
132
+ <xsl:with-param name="s" select="substring-before($s,'\')"/>
133
+ </xsl:call-template>
134
+ <xsl:text>\\</xsl:text>
135
+ <xsl:call-template name="escape-string">
136
+ <xsl:with-param name="s" select="substring-after($s,'\')"/>
137
+ </xsl:call-template>
138
+ </xsl:when>
139
+ <xsl:when test="contains($s,'&quot;') and contains($s,'\')">
140
+ <xsl:choose>
141
+ <!-- double quote before backslash -->
142
+ <xsl:when test="string-length(substring-before($s,'&quot;'))&lt;string-length(substring-before($s,'\'))">
143
+ <xsl:call-template name="encode-string">
144
+ <xsl:with-param name="s" select="substring-before($s,'&quot;')"/>
145
+ </xsl:call-template>
146
+ <xsl:text>\"</xsl:text>
147
+ <xsl:call-template name="escape-string">
148
+ <xsl:with-param name="s" select="substring-after($s,'&quot;')"/>
149
+ </xsl:call-template>
150
+ </xsl:when>
151
+ <!-- backslash before double quote -->
152
+ <xsl:when test="string-length(substring-before($s,'&quot;'))&gt;string-length(substring-before($s,'\'))">
153
+ <xsl:call-template name="encode-string">
154
+ <xsl:with-param name="s" select="substring-before($s,'\')"/>
155
+ </xsl:call-template>
156
+ <xsl:text>\\</xsl:text>
157
+ <xsl:call-template name="escape-string">
158
+ <xsl:with-param name="s" select="substring-after($s,'\')"/>
159
+ </xsl:call-template>
160
+ </xsl:when>
161
+ </xsl:choose>
162
+ </xsl:when>
163
+ <xsl:otherwise>
164
+ <xsl:call-template name="encode-string">
165
+ <xsl:with-param name="s" select="$s"/>
166
+ </xsl:call-template>
167
+ </xsl:otherwise>
168
+ </xsl:choose>
169
+ </xsl:template>
170
+
171
+ <!-- Replace tab, line feed and/or carriage return by its matching escape code. Also escape tag-close
172
+ (</tag> to <\/tag> for client-side javascript compliance). Can't escape backslash
173
+ or double quote here, because they don't replace characters (&#x0; becomes \t), but they prefix
174
+ characters (\ becomes \\). Besides, backslash should be seperate anyway, because it should be
175
+ processed first. This function can't do that. -->
176
+ <xsl:template name="encode-string">
177
+ <xsl:param name="s"/>
178
+ <xsl:choose>
179
+ <!-- tab -->
180
+ <xsl:when test="contains($s,'&#x9;')">
181
+ <xsl:call-template name="encode-string">
182
+ <xsl:with-param name="s" select="concat(substring-before($s,'&#x9;'),'\t',substring-after($s,'&#x9;'))"/>
183
+ </xsl:call-template>
184
+ </xsl:when>
185
+ <!-- line feed -->
186
+ <xsl:when test="contains($s,'&#xA;')">
187
+ <xsl:call-template name="encode-string">
188
+ <xsl:with-param name="s" select="concat(substring-before($s,'&#xA;'),'\n',substring-after($s,'&#xA;'))"/>
189
+ </xsl:call-template>
190
+ </xsl:when>
191
+ <!-- carriage return -->
192
+ <xsl:when test="contains($s,'&#xD;')">
193
+ <xsl:call-template name="encode-string">
194
+ <xsl:with-param name="s" select="concat(substring-before($s,'&#xD;'),'\r',substring-after($s,'&#xD;'))"/>
195
+ </xsl:call-template>
196
+ </xsl:when>
197
+ <!-- JS: tag-close -->
198
+ <xsl:when test="contains($s,'&lt;/')">
199
+ <xsl:call-template name="encode-string">
200
+ <xsl:with-param name="s" select="concat(substring-before($s,'&lt;/'),'&lt;\/',substring-after($s,'&lt;/'))"/>
201
+ </xsl:call-template>
202
+ </xsl:when>
203
+ <xsl:otherwise><xsl:value-of select="$s"/></xsl:otherwise>
204
+ </xsl:choose>
205
+ </xsl:template>
206
+
207
+ <!-- number (no support for javascript mantise) -->
208
+ <xsl:template match="text()[not(string(number())='NaN')]">
209
+ <xsl:value-of select="."/>
210
+ </xsl:template>
211
+
212
+ <!-- boolean, case-insensitive -->
213
+ <xsl:template match="text()[translate(.,'TRUE','true')='true']">true</xsl:template>
214
+ <xsl:template match="text()[translate(.,'FALSE','false')='false']">false</xsl:template>
215
+
216
+ <!-- JS: Date: YYYY-dd-mm[Thh] -->
217
+ <xsl:template match="text()[string-length()=10
218
+ and string-length(translate(substring(.,1,4),'0123456789',''))=0
219
+ and substring(.,5,1)='-'
220
+ and string-length(translate(substring(.,6,2),'0123456789',''))=0
221
+ and substring(.,8,1)='-'
222
+ and string-length(translate(substring(.,9,2),'0123456789',''))=0
223
+ ]">
224
+ <xsl:text>new Date(</xsl:text>
225
+ <xsl:value-of select="substring(.,1,4)"/>
226
+ <xsl:text>,</xsl:text>
227
+ <xsl:value-of select="substring(.,6,2)"/>
228
+ <xsl:text>-1,</xsl:text>
229
+ <xsl:value-of select="substring(.,9,2)"/>
230
+ <xsl:text>)</xsl:text>
231
+ </xsl:template>
232
+ <!-- JS: Date: YYYY-dd-mmThh:mm -->
233
+ <xsl:template match="text()[string-length()=16
234
+ and string-length(translate(substring(.,1,4),'0123456789',''))=0
235
+ and substring(.,5,1)='-'
236
+ and string-length(translate(substring(.,6,2),'0123456789',''))=0
237
+ and substring(.,8,1)='-'
238
+ and string-length(translate(substring(.,9,2),'0123456789',''))=0
239
+ and substring(.,11,1)='T'
240
+ and string-length(translate(substring(.,12,2),'0123456789',''))=0
241
+ and substring(.,14,1)=':'
242
+ and string-length(translate(substring(.,15,2),'0123456789',''))=0
243
+ ]">
244
+ <xsl:text>new Date(</xsl:text>
245
+ <xsl:value-of select="substring(.,1,4)"/>
246
+ <xsl:text>,</xsl:text>
247
+ <xsl:value-of select="substring(.,6,2)"/>
248
+ <xsl:text>-1,</xsl:text>
249
+ <xsl:value-of select="substring(.,9,2)"/>
250
+ <xsl:text>,</xsl:text>
251
+ <xsl:value-of select="substring(.,12,2)"/>
252
+ <xsl:text>,</xsl:text>
253
+ <xsl:value-of select="substring(.,15,2)"/>
254
+ <xsl:text>)</xsl:text>
255
+ </xsl:template>
256
+ <!-- JS: Date: YYYY-dd-mmThh:mm:ss -->
257
+ <xsl:template match="text()[string-length()=19
258
+ and string-length(translate(substring(.,1,4),'0123456789',''))=0
259
+ and substring(.,5,1)='-'
260
+ and string-length(translate(substring(.,6,2),'0123456789',''))=0
261
+ and substring(.,8,1)='-'
262
+ and string-length(translate(substring(.,9,2),'0123456789',''))=0
263
+ and substring(.,11,1)='T'
264
+ and string-length(translate(substring(.,12,2),'0123456789',''))=0
265
+ and substring(.,14,1)=':'
266
+ and string-length(translate(substring(.,15,2),'0123456789',''))=0
267
+ and substring(.,17,1)=':'
268
+ and string-length(translate(substring(.,18,2),'0123456789',''))=0
269
+ ]">
270
+ <xsl:text>new Date(</xsl:text>
271
+ <xsl:value-of select="substring(.,1,4)"/>
272
+ <xsl:text>,</xsl:text>
273
+ <xsl:value-of select="substring(.,6,2)"/>
274
+ <xsl:text>-1,</xsl:text>
275
+ <xsl:value-of select="substring(.,9,2)"/>
276
+ <xsl:text>,</xsl:text>
277
+ <xsl:value-of select="substring(.,12,2)"/>
278
+ <xsl:text>,</xsl:text>
279
+ <xsl:value-of select="substring(.,15,2)"/>
280
+ <xsl:text>,</xsl:text>
281
+ <xsl:value-of select="substring(.,18,2)"/>
282
+ <xsl:text>)</xsl:text>
283
+ </xsl:template>
284
+
285
+ <!-- item:null -->
286
+ <xsl:template match="*[count(child::node())=0]">
287
+ <xsl:call-template name="indent"/>
288
+ <xsl:call-template name="quote-property">
289
+ <xsl:with-param name="name" select="local-name()"/>
290
+ </xsl:call-template>
291
+ <xsl:text>:null</xsl:text>
292
+ <xsl:if test="following-sibling::*">,</xsl:if>
293
+ </xsl:template>
294
+
295
+ <!-- object -->
296
+ <xsl:template match="*" name="base">
297
+ <xsl:if test="not(preceding-sibling::*)">{</xsl:if>
298
+ <xsl:call-template name="indent"/>
299
+ <!-- JS: handle attributes -->
300
+ <xsl:call-template name="attrs">
301
+ <xsl:with-param name="attrs" select="../@*"/>
302
+ </xsl:call-template>
303
+ <xsl:call-template name="quote-property">
304
+ <xsl:with-param name="name" select="name()"/>
305
+ </xsl:call-template>
306
+ <xsl:text>:</xsl:text>
307
+ <xsl:apply-templates select="child::node()"/>
308
+ <xsl:if test="following-sibling::*">,</xsl:if>
309
+ <xsl:if test="not(following-sibling::*)">}</xsl:if>
310
+ </xsl:template>
311
+
312
+ <!-- JS: don't quote if not necessary -->
313
+ <xsl:template name="quote-property">
314
+ <xsl:param name="name"/>
315
+ <xsl:choose>
316
+ <xsl:when test="contains(',abstract,boolean,break,byte,case,catch,char,class,const,continue,debugger,default,delete,do,double,else,enum,export,extends,final,finally,float,for,function,goto,if,implements,import,in,instanceof,int,interface,long,native,new,package,private,protected,public,return,short,static,super,switch,synchronized,this,throw,throws,transient,try,typeof,var,void,volatile,while,with,',concat(',',$name,',')) or not(translate($name,'.-:','')=$name)">
317
+ <xsl:call-template name="escape-string">
318
+ <xsl:with-param name="s" select="$name"/>
319
+ </xsl:call-template>
320
+ </xsl:when>
321
+ <xsl:otherwise>
322
+ <xsl:value-of select="$name"/>
323
+ </xsl:otherwise>
324
+ </xsl:choose>
325
+ </xsl:template>
326
+
327
+ <!-- array -->
328
+ <xsl:template match="*[count(../*[name(../*)=name(.)])=count(../*) and count(../*)&gt;1]">
329
+ <xsl:if test="not(preceding-sibling::*)">[</xsl:if>
330
+ <xsl:call-template name="indent"/>
331
+ <xsl:choose>
332
+ <xsl:when test="not(child::node())">
333
+ <xsl:text>null</xsl:text>
334
+ </xsl:when>
335
+ <xsl:otherwise>
336
+ <xsl:apply-templates select="child::node()"/>
337
+ </xsl:otherwise>
338
+ </xsl:choose>
339
+ <xsl:if test="following-sibling::*">,</xsl:if>
340
+ <xsl:if test="not(following-sibling::*)">]</xsl:if>
341
+ </xsl:template>
342
+
343
+ <!-- JS: indent for reability -->
344
+ <xsl:template name="indent">
345
+ <xsl:text>
346
+ </xsl:text>
347
+ <xsl:for-each select="ancestor::*">
348
+ <xsl:text> </xsl:text>
349
+ </xsl:for-each>
350
+ </xsl:template>
351
+
352
+ <!-- JS: include comments -->
353
+ <xsl:template match="comment()">/*<xsl:value-of select="."/>*/</xsl:template>
354
+
355
+ <!-- convert root element to an anonymous container -->
356
+ <xsl:template match="/*">
357
+ <xsl:apply-templates select="node()"/>
358
+ </xsl:template>
359
+
360
+ </xsl:stylesheet>
@@ -0,0 +1,178 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
3
+ <!--
4
+ Copyright (c) 2006, Doeke Zanstra
5
+ All rights reserved.
6
+
7
+ Redistribution and use in source and binary forms, with or without modification,
8
+ are permitted provided that the following conditions are met:
9
+
10
+ Redistributions of source code must retain the above copyright notice, this
11
+ list of conditions and the following disclaimer. Redistributions in binary
12
+ form must reproduce the above copyright notice, this list of conditions and the
13
+ following disclaimer in the documentation and/or other materials provided with
14
+ the distribution.
15
+
16
+ Neither the name of the dzLib nor the names of its contributors may be used to
17
+ endorse or promote products derived from this software without specific prior
18
+ written permission.
19
+
20
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
21
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23
+ IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
24
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
25
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
29
+ THE POSSIBILITY OF SUCH DAMAGE.
30
+ -->
31
+
32
+ <xsl:output indent="no" omit-xml-declaration="yes" method="text" encoding="UTF-8" media-type="text/x-json"/>
33
+ <xsl:strip-space elements="*"/>
34
+ <!--contant-->
35
+ <xsl:variable name="d">0123456789</xsl:variable>
36
+
37
+ <!-- ignore document text -->
38
+ <xsl:template match="text()[preceding-sibling::node() or following-sibling::node()]"/>
39
+
40
+ <!-- string -->
41
+ <xsl:template match="text()">
42
+ <xsl:call-template name="escape-string">
43
+ <xsl:with-param name="s" select="."/>
44
+ </xsl:call-template>
45
+ </xsl:template>
46
+
47
+ <!-- Main template for escaping strings; used by above template and for object-properties
48
+ Responsibilities: placed quotes around string, and chain up to next filter, escape-bs-string -->
49
+ <xsl:template name="escape-string">
50
+ <xsl:param name="s"/>
51
+ <xsl:text>"</xsl:text>
52
+ <xsl:call-template name="escape-bs-string">
53
+ <xsl:with-param name="s" select="$s"/>
54
+ </xsl:call-template>
55
+ <xsl:text>"</xsl:text>
56
+ </xsl:template>
57
+
58
+ <!-- Escape the backslash (\) before everything else. -->
59
+ <xsl:template name="escape-bs-string">
60
+ <xsl:param name="s"/>
61
+ <xsl:choose>
62
+ <xsl:when test="contains($s,'\')">
63
+ <xsl:call-template name="escape-quot-string">
64
+ <xsl:with-param name="s" select="concat(substring-before($s,'\'),'\\')"/>
65
+ </xsl:call-template>
66
+ <xsl:call-template name="escape-bs-string">
67
+ <xsl:with-param name="s" select="substring-after($s,'\')"/>
68
+ </xsl:call-template>
69
+ </xsl:when>
70
+ <xsl:otherwise>
71
+ <xsl:call-template name="escape-quot-string">
72
+ <xsl:with-param name="s" select="$s"/>
73
+ </xsl:call-template>
74
+ </xsl:otherwise>
75
+ </xsl:choose>
76
+ </xsl:template>
77
+
78
+ <!-- Escape the double quote ("). -->
79
+ <xsl:template name="escape-quot-string">
80
+ <xsl:param name="s"/>
81
+ <xsl:choose>
82
+ <xsl:when test="contains($s,'&quot;')">
83
+ <xsl:call-template name="encode-string">
84
+ <xsl:with-param name="s" select="concat(substring-before($s,'&quot;'),'\&quot;')"/>
85
+ </xsl:call-template>
86
+ <xsl:call-template name="escape-quot-string">
87
+ <xsl:with-param name="s" select="substring-after($s,'&quot;')"/>
88
+ </xsl:call-template>
89
+ </xsl:when>
90
+ <xsl:otherwise>
91
+ <xsl:call-template name="encode-string">
92
+ <xsl:with-param name="s" select="$s"/>
93
+ </xsl:call-template>
94
+ </xsl:otherwise>
95
+ </xsl:choose>
96
+ </xsl:template>
97
+
98
+ <!-- Replace tab, line feed and/or carriage return by its matching escape code. Can't escape backslash
99
+ or double quote here, because they don't replace characters (&#x0; becomes \t), but they prefix
100
+ characters (\ becomes \\). Besides, backslash should be seperate anyway, because it should be
101
+ processed first. This function can't do that. -->
102
+ <xsl:template name="encode-string">
103
+ <xsl:param name="s"/>
104
+ <xsl:choose>
105
+ <!-- tab -->
106
+ <xsl:when test="contains($s,'&#x9;')">
107
+ <xsl:call-template name="encode-string">
108
+ <xsl:with-param name="s" select="concat(substring-before($s,'&#x9;'),'\t',substring-after($s,'&#x9;'))"/>
109
+ </xsl:call-template>
110
+ </xsl:when>
111
+ <!-- line feed -->
112
+ <xsl:when test="contains($s,'&#xA;')">
113
+ <xsl:call-template name="encode-string">
114
+ <xsl:with-param name="s" select="concat(substring-before($s,'&#xA;'),'\n',substring-after($s,'&#xA;'))"/>
115
+ </xsl:call-template>
116
+ </xsl:when>
117
+ <!-- carriage return -->
118
+ <xsl:when test="contains($s,'&#xD;')">
119
+ <xsl:call-template name="encode-string">
120
+ <xsl:with-param name="s" select="concat(substring-before($s,'&#xD;'),'\r',substring-after($s,'&#xD;'))"/>
121
+ </xsl:call-template>
122
+ </xsl:when>
123
+ <xsl:otherwise><xsl:value-of select="$s"/></xsl:otherwise>
124
+ </xsl:choose>
125
+ </xsl:template>
126
+
127
+ <!-- number (no support for javascript mantise) -->
128
+ <xsl:template match="text()[not(string(number())='NaN')]">
129
+ <xsl:value-of select="."/>
130
+ </xsl:template>
131
+
132
+ <!-- boolean, case-insensitive -->
133
+ <xsl:template match="text()[translate(.,'TRUE','true')='true']">true</xsl:template>
134
+ <xsl:template match="text()[translate(.,'FALSE','false')='false']">false</xsl:template>
135
+
136
+ <!-- item:null -->
137
+ <xsl:template match="*[count(child::node())=0]">
138
+ <xsl:call-template name="escape-string">
139
+ <xsl:with-param name="s" select="local-name()"/>
140
+ </xsl:call-template>
141
+ <xsl:text>:null</xsl:text>
142
+ <xsl:if test="following-sibling::*">,</xsl:if>
143
+ <xsl:if test="not(following-sibling::*)">}</xsl:if>
144
+ </xsl:template>
145
+
146
+ <!-- object -->
147
+ <xsl:template match="*" name="base">
148
+ <xsl:if test="not(preceding-sibling::*)">{</xsl:if>
149
+ <xsl:call-template name="escape-string">
150
+ <xsl:with-param name="s" select="name()"/>
151
+ </xsl:call-template>
152
+ <xsl:text>:</xsl:text>
153
+ <xsl:apply-templates select="child::node()"/>
154
+ <xsl:if test="following-sibling::*">,</xsl:if>
155
+ <xsl:if test="not(following-sibling::*)">}</xsl:if>
156
+ </xsl:template>
157
+
158
+ <!-- array -->
159
+ <xsl:template match="*[count(../*[name(../*)=name(.)])=count(../*) and count(../*)>1]">
160
+ <xsl:if test="not(preceding-sibling::*)">[</xsl:if>
161
+ <xsl:choose>
162
+ <xsl:when test="not(child::node())">
163
+ <xsl:text>null</xsl:text>
164
+ </xsl:when>
165
+ <xsl:otherwise>
166
+ <xsl:apply-templates select="child::node()"/>
167
+ </xsl:otherwise>
168
+ </xsl:choose>
169
+ <xsl:if test="following-sibling::*">,</xsl:if>
170
+ <xsl:if test="not(following-sibling::*)">]</xsl:if>
171
+ </xsl:template>
172
+
173
+ <!-- convert root element to an anonymous container -->
174
+ <xsl:template match="/">
175
+ <xsl:apply-templates select="node()"/>
176
+ </xsl:template>
177
+
178
+ </xsl:stylesheet>