Project

Profile

Help

How to connect?
Download (8.28 KB) Statistics
| Branch: | Tag: | Revision:

he / tags / 9.7.0.3 / hej / data / xml-to-json-pkg.xsl @ cb770b3c

1
<?xml version="1.0" encoding="UTF-8"?>
2

    
3
<xsl:package name="http://www.w3.org/2013/XSLT/xml-to-json.xsl"
4
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema"
5
    xmlns:j="http://www.w3.org/2005/xpath-functions/json" exclude-result-prefixes="xs j"
6
    default-mode="j:xml-to-json" version="3.0" package-version="3.0">
7

    
8
    <xsl:stylesheet>
9

    
10
        <!-- The delimiter to be used before and after keys in a map -->
11
        <xsl:param name="j:key-delimiter" as="xs:string">"</xsl:param>
12

    
13
        <!-- The delimiter to be used before and after string values -->
14
        <xsl:param name="j:string-delimiter" as="xs:string">"</xsl:param>
15

    
16
        <!-- The separator to be used between keys and values -->
17
        <xsl:param name="j:key-value-separator" as="xs:string">:</xsl:param>
18

    
19
        <!-- The separator to be used between entries in a map -->
20
        <xsl:param name="j:map-separator" as="xs:string">,</xsl:param>
21

    
22
        <!-- The opening delimiter of an array -->
23
        <xsl:param name="j:start-array" as="xs:string">[</xsl:param>
24

    
25
        <!-- The closing delimiter of an array -->
26
        <xsl:param name="j:end-array" as="xs:string">]</xsl:param>
27

    
28
        <!-- The opening delimiter of a map -->
29
        <xsl:param name="j:start-map" as="xs:string">{</xsl:param>
30

    
31
        <!-- The closing delimiter of a map -->
32
        <xsl:param name="j:end-map" as="xs:string">}</xsl:param>
33

    
34
        <!-- The separator to be used between members of an array -->
35
        <xsl:param name="j:array-separator" as="xs:string">,</xsl:param>
36

    
37
        <xsl:template name="j:start-array">
38
            <xsl:value-of select="$j:start-array"/>
39
        </xsl:template>
40

    
41
        <xsl:template name="j:end-array">
42
            <xsl:value-of select="$j:end-array"/>
43
        </xsl:template>
44

    
45
        <xsl:template name="j:start-map">
46
            <xsl:value-of select="$j:start-map"/>
47
        </xsl:template>
48

    
49
        <xsl:template name="j:end-map">
50
            <xsl:value-of select="$j:end-map"/>
51
        </xsl:template>
52

    
53
        <xsl:template name="j:key-value-separator">
54
            <xsl:value-of select="$j:key-value-separator"/>
55
        </xsl:template>
56
        <xsl:template name="j:map-separator">
57
            <xsl:value-of select="$j:map-separator"/>
58
        </xsl:template>
59

    
60
        <xsl:template name="j:array-separator">
61
            <xsl:value-of select="$j:array-separator"/>
62
        </xsl:template>
63

    
64
        <!-- Entry point: function to convert a supplied XML node to a JSON string -->
65
        <xsl:function name="j:xml-to-json" as="xs:string" visibility="public">
66
            <xsl:param name="xml" as="node()"/>
67
            <xsl:variable name="parts" as="xs:string*">
68
                <xsl:apply-templates select="$xml"/>
69
            </xsl:variable>
70
            <xsl:value-of select="string-join($parts,'')"/>
71
        </xsl:function>
72
        <!-- Entry point: named template to convert a supplied XML node to a JSON string -->
73
        <xsl:template name="j:xml-to-json" as="xs:string" visibility="public">
74
            <xsl:param name="xml" as="node()" select="."/>
75
            <xsl:value-of select="j:xml-to-json($xml)"/>
76
        </xsl:template>
77

    
78
        <!-- Conversion of XML to JSON can be achieved by applying templates to the XML root in this mode -->
79
        <xsl:mode name="j:xml-to-json" streamable="yes" visibility="public"
80
            on-no-match="shallow-copy"/>
81

    
82
        <!-- Template rule for j:map elements, representing JSON objects -->
83
        <xsl:template match="j:map">
84
            <xsl:call-template name="j:start-map"/>
85
            <xsl:for-each select="*">
86
                <xsl:if test="position() gt 1">
87
                    <xsl:call-template name="j:map-separator"/>
88
                </xsl:if>
89
                <xsl:apply-templates select="@key"/>
90
                <xsl:call-template name="j:key-value-separator"/>
91
                <xsl:apply-templates select="."/>
92
            </xsl:for-each>
93
            <xsl:call-template name="j:end-map"/>
94
        </xsl:template>
95

    
96
        <!-- Template rule for j:array elements, representing JSON arrays -->
97
        <xsl:template match="j:array">
98
            <xsl:call-template name="j:start-array"/>
99
            <xsl:for-each select="*">
100
                <xsl:if test="position() gt 1">
101
                    <xsl:call-template name="j:array-separator"/>
102
                </xsl:if>
103
                <xsl:apply-templates select="."/>
104
            </xsl:for-each>
105
            <xsl:call-template name="j:end-array"/>
106
        </xsl:template>
107

    
108
        <!-- Template rule for j:string elements in which special characters are already escaped -->
109
        <xsl:template match="j:string[@escaped='true']">
110
            <xsl:value-of select="concat($j:string-delimiter, ., $j:string-delimiter)"/>
111
        </xsl:template>
112

    
113
        <!-- Template rule for j:string elements in which special characters need to be escaped -->
114
        <xsl:template match="j:string[not(@escaped='true')]">
115
            <xsl:value-of select="concat($j:string-delimiter, j:escape(.), $j:string-delimiter)"/>
116
        </xsl:template>
117

    
118
        <!-- Template rule for j:number and j:boolean elements (representing JSON numbers and booleans) -->
119
        <xsl:template match="j:number | j:boolean">
120
            <xsl:value-of select="."/>
121
        </xsl:template>
122

    
123
        <!-- Template rule for JSON null elements (representing JSON null values) -->
124
        <xsl:template match="j:null">
125
            <xsl:text>null</xsl:text>
126
        </xsl:template>
127

    
128
        <!-- Template rule matching a key within a map where special characters in the key are already escaped -->
129
        <xsl:template match="j:*/@key[../@key-escaped='true']">
130
            <xsl:value-of select="concat($j:key-delimiter, ., $j:key-delimiter)"/>
131
        </xsl:template>
132

    
133
        <!-- Template rule matching a key within a map where special characters in the key need to be escaped -->
134
        <xsl:template match="j:*/@key[not(../@key-escaped='true')]">
135
            <xsl:value-of select="concat($j:key-delimiter, j:escape(.), $j:key-delimiter)"/>
136
        </xsl:template>
137

    
138
        <!-- Template rule matching (and discarding) text nodes in the XML: typically ignorable whitespace -->
139
        <xsl:template match="text()"/>
140

    
141
        <!-- Function to escape special characters -->
142
        <xsl:function name="j:escape" as="xs:string">
143
            <xsl:param name="in" as="xs:string"/>
144
            <xsl:value-of>
145
                <xsl:for-each select="string-to-codepoints($in)">
146
                    <xsl:choose>
147
                        <xsl:when test=". gt 65535">
148
                            <xsl:value-of
149
                                select="concat('\u', j:hex4((. - 65536) idiv 1024 + 55296))"/>
150
                            <xsl:value-of
151
                                select="concat('\u', j:hex4((. - 65536) mod 1024 + 56320))"/>
152
                        </xsl:when>
153
                        <xsl:when test=". = 34">\"</xsl:when>
154
                        <xsl:when test=". = 92">\\</xsl:when>
155
                        <xsl:when test=". = 08">\b</xsl:when>
156
                        <xsl:when test=". = 09">\t</xsl:when>
157
                        <xsl:when test=". = 10">\n</xsl:when>
158
                        <xsl:when test=". = 12">\f</xsl:when>
159
                        <xsl:when test=". = 13">\r</xsl:when>
160
                        <xsl:when test=". lt 32 or (. ge 127 and . le 160)">
161
                            <xsl:value-of select="concat('\u', j:hex4(.))"/>
162
                        </xsl:when>
163
                        <xsl:otherwise>
164
                            <xsl:value-of select="codepoints-to-string(.)"/>
165
                        </xsl:otherwise>
166
                    </xsl:choose>
167
                </xsl:for-each>
168
            </xsl:value-of>
169
        </xsl:function>
170

    
171
        <!-- Function to convert a UTF16 codepoint into a string of four hex digits -->
172
        <xsl:function name="j:hex4" as="xs:string">
173
            <xsl:param name="ch" as="xs:integer"/>
174
            <xsl:variable name="hex" select="'0123456789abcdef'"/>
175
            <xsl:value-of>
176
                <xsl:value-of select="substring($hex, $ch idiv 4096 + 1, 1)"/>
177
                <xsl:value-of select="substring($hex, $ch idiv 256 mod 16 + 1, 1)"/>
178
                <xsl:value-of select="substring($hex, $ch idiv 16 mod 16 + 1, 1)"/>
179
                <xsl:value-of select="substring($hex, $ch mod 16 + 1, 1)"/>
180
            </xsl:value-of>
181
        </xsl:function>
182

    
183
    </xsl:stylesheet>
184

    
185
</xsl:package>
(10-10/12)