├── unittests ├── issue6.json.expected ├── single.js.expected ├── issue2.json.expected ├── single.json.expected ├── issue1.json.expected ├── issue12.json.expected ├── single.xml ├── issue12.js.expected ├── dates.json.expected ├── xmlisms.json.expected ├── nodes.json.expected ├── dates.js.expected ├── types.json.expected ├── numbers.json.expected ├── xmlisms.js.expected ├── nodes.js.expected ├── issue2.js.expected ├── issue1.js.expected ├── issue12.xml ├── issue6.xml ├── numbers.js.expected ├── xmlisms.xml ├── issue2.xml ├── nodes.xml ├── dates.xml ├── issue1.xml ├── numbers.xml ├── types.js.expected ├── types.xml ├── strings.json.expected ├── strings.js.expected └── strings.xml ├── README.md ├── COPYRIGHT ├── Makefile ├── xml2json.xslt └── xml2js.xslt /unittests/issue6.json.expected: -------------------------------------------------------------------------------- 1 | {"array":["one"]} 2 | -------------------------------------------------------------------------------- /unittests/single.js.expected: -------------------------------------------------------------------------------- 1 | "This is a test of a single text node." 2 | -------------------------------------------------------------------------------- /unittests/issue2.json.expected: -------------------------------------------------------------------------------- 1 | {"root":{"octal":"01234567","notoctal":"089"}} 2 | -------------------------------------------------------------------------------- /unittests/single.json.expected: -------------------------------------------------------------------------------- 1 | {"root":"This is a test of a single text node."} 2 | -------------------------------------------------------------------------------- /unittests/issue1.json.expected: -------------------------------------------------------------------------------- 1 | {"productRating":{"rating":{"ratingCode":"PG-13"},"explaination":null}} 2 | -------------------------------------------------------------------------------- /unittests/issue12.json.expected: -------------------------------------------------------------------------------- 1 | {"zoo":{"fish":{"name":"whale","weight":null},"bird":{"name":"owl"}}} 2 | -------------------------------------------------------------------------------- /unittests/single.xml: -------------------------------------------------------------------------------- 1 | 2 | This is a test of a single text node. 3 | -------------------------------------------------------------------------------- /unittests/issue12.js.expected: -------------------------------------------------------------------------------- 1 | { 2 | fish:{ 3 | name:"whale", 4 | weight:null}, 5 | bird:{ 6 | name:"owl"}} 7 | -------------------------------------------------------------------------------- /unittests/dates.json.expected: -------------------------------------------------------------------------------- 1 | {"dates":{"birthdate":"2006-11-14","appointment":"2006-11-14T12:30","appointment":"2006-11-14T12:30:00"}} 2 | -------------------------------------------------------------------------------- /unittests/xmlisms.json.expected: -------------------------------------------------------------------------------- 1 | {"text":"\n \n
\nThis is \"text\", <dude>.\nc:\\windows\n
\n\n"} 2 | -------------------------------------------------------------------------------- /unittests/nodes.json.expected: -------------------------------------------------------------------------------- 1 | {"nodes":{"ding:dong-dang.dung":"Namespaced element with dash and dot","yo123-ho456":null,"yo123-ho457":"data","nil":null,"empty":null}} 2 | -------------------------------------------------------------------------------- /unittests/dates.js.expected: -------------------------------------------------------------------------------- 1 | { 2 | birthdate:new Date(2006,11-1,14), 3 | appointment:new Date(2006,11-1,14,12,30), 4 | appointment:new Date(2006,11-1,14,12,30,00)} 5 | -------------------------------------------------------------------------------- /unittests/types.json.expected: -------------------------------------------------------------------------------- 1 | {"types":{"true-boolean":true,"false-boolean":false,"object":{"zooi":"jaja","zut":"frot"},"array":[null,true,2,3,4,5,"six",{"key":"item","value":7}]}} 2 | -------------------------------------------------------------------------------- /unittests/numbers.json.expected: -------------------------------------------------------------------------------- 1 | {"root":{"zero":0,"fixed":10.25,"octal":"0123","hex":"0x123","padded_zero":"01","fixed-neg":-10.25,"int":123,"int-neg":-321,"float":-12.123,"exp":-1.234e5}} 2 | -------------------------------------------------------------------------------- /unittests/xmlisms.js.expected: -------------------------------------------------------------------------------- 1 | /* 2 | XML-isms in a giant blob of text. 3 | */"\n \n
\nThis is \"text\", <dude>.<\/span>\nc:\\windows<\/span>\n<\/div>\n\n" 4 | -------------------------------------------------------------------------------- /unittests/nodes.js.expected: -------------------------------------------------------------------------------- 1 | { 2 | "ding:dong-dang.dung":"Namespaced element with dash and dot", 3 | "yo123-ho456":null, 4 | "yo123-ho457":"data", 5 | nil:null, 6 | empty:null} 7 | -------------------------------------------------------------------------------- /unittests/issue2.js.expected: -------------------------------------------------------------------------------- 1 | /* 2 | Test Case submitted in issue 2: Invalid octals 3 | http://code.google.com/p/xml2json-xslt/issues/detail?id=2 4 | */{ 5 | octal:"01234567", 6 | notoctal:"089"} 7 | -------------------------------------------------------------------------------- /unittests/issue1.js.expected: -------------------------------------------------------------------------------- 1 | /* 2 | Test Case submitted in issue 1: 3 | http://code.google.com/p/xml2json-xslt/issues/detail?id=1 4 | */{ 5 | rating:{ 6 | ratingCode:"PG-13"}, 7 | explaination:null} 8 | -------------------------------------------------------------------------------- /unittests/issue12.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | whale 5 | 6 | 7 | 8 | owl 9 | 10 | 11 | -------------------------------------------------------------------------------- /unittests/issue6.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | one 8 | 9 | -------------------------------------------------------------------------------- /unittests/numbers.js.expected: -------------------------------------------------------------------------------- 1 | { 2 | zero:0, 3 | fixed:10.25, 4 | octal:"0123", 5 | hex:"0x123", 6 | padded_zero:"01", 7 | "fixed-neg":-10.25, 8 | "int":123, 9 | "int-neg":-321, 10 | "float":-12.123, 11 | exp:-1.234e5} 12 | -------------------------------------------------------------------------------- /unittests/xmlisms.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 8 | This is "text", <dude>. 9 | c:\windows 10 |
11 | ]]> 12 | 13 | -------------------------------------------------------------------------------- /unittests/issue2.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 01234567 8 | 089 9 | 10 | -------------------------------------------------------------------------------- /unittests/nodes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Namespaced element with dash and dot 4 | 5 | data 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /unittests/dates.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | This should be ignored, as usual. 4 | 2006-11-14 5 | 2006-11-14T12:30 6 | 2006-11-14T12:30:00 7 | 8 | -------------------------------------------------------------------------------- /unittests/issue1.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | PG-13 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /unittests/numbers.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 0 4 | 10.25 5 | 0123 6 | 0x123 7 | 01 8 | -10.25 9 | 123 10 | -321 11 | -12.123 12 | -1.234e5 13 | 14 | -------------------------------------------------------------------------------- /unittests/types.js.expected: -------------------------------------------------------------------------------- 1 | { 2 | "true-boolean":true, 3 | "false-boolean":false, 4 | /*@test="true" @attributes="are commented in js"*/object:{ 5 | zooi:"jaja", 6 | zut:"frot"}, 7 | array:[ 8 | null, 9 | true, 10 | 2, 11 | 3, 12 | 4, 13 | 5, 14 | "six", 15 | { 16 | key:"item", 17 | value:7}]} 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Notice 2 | ------ 3 | This project is migrated from Google Code, and is kept here for reference only. 4 | 5 | 6 | XML2JSON-XSLT 7 | ------------- 8 | 9 | These are XSLT stylesheets that transform arbitrary XML to JSON (and JS). 10 | 11 | For more information, please read our wiki: 12 | http://code.google.com/p/xml2json-xslt/wiki/TransformingRules 13 | 14 | If you are interested in running the test cases, please check out a 15 | copy of our source from SVN: 16 | http://code.google.com/p/xml2json-xslt/source/checkout 17 | 18 | -------------------------------------------------------------------------------- /unittests/types.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | true 4 | false 5 | 6 | jaja 7 | frot 8 | 9 | 10 | 11 | true 12 | 2 13 | 3 14 | 4 15 | 5 16 | six 17 | 18 | item 19 | 7 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /unittests/strings.json.expected: -------------------------------------------------------------------------------- 1 | {"strings":{"script":"","string":"Zooi","string":"Tab\tText","string":"Quote \"test\"","string":"Backslash \\ test","string":"Quote \" en \\ test","string":"\"Forsooth! It 'tis as I thought!\"","string":"\"Begin/end quote\"","escape":"Line one (één in Dutch)\nLine two:\ttab\nHe said: \"Much fun with a €\"\nMore unicode†","poetry":"JABBERWOCKY\n\nLewis Carroll\n\n(from Through the Looking-Glass and What Alice Found There, 1872)\n`Twas brillig, and the slithy toves\n Did gyre and gimble in the wabe:\nAll mimsy were the borogoves,\n And the mome raths outgrabe.\n\n \n\n\"Beware the Jabberwock, my son!\n The jaws that bite, the claws that catch!\nBeware the Jubjub bird, and shun\n The frumious Bandersnatch!\"\nHe took his vorpal sword in hand:\n Long time the manxome foe he sought --\nSo rested he by the Tumtum tree,\n And stood awhile in thought.\nAnd, as in uffish thought he stood,\n The Jabberwock, with eyes of flame,\nCame whiffling through the tulgey wood,\n And burbled as it came!\nOne, two! One, two! And through and through\n The vorpal blade went snicker-snack!\nHe left it dead, and with its head\n He went galumphing back.\n\"And, has thou slain the Jabberwock?\n Come to my arms, my beamish boy!\nO frabjous day! Callooh! Callay!'\n He chortled in his joy.\n\n\n\n`Twas brillig, and the slithy toves\n Did gyre and gimble in the wabe;\nAll mimsy were the borogoves,\n And the mome raths outgrabe."}} 2 | -------------------------------------------------------------------------------- /unittests/strings.js.expected: -------------------------------------------------------------------------------- 1 | { 2 | script:"]]> 5 | Zooi 6 | Tab Text 7 | Quote "test" 8 | Backslash \ test 9 | Quote " en \ test 10 | "Forsooth! It 'tis as I thought!" 11 | "Begin/end quote" 12 | Line one (één in Dutch) 13 | Line two: tab 14 | He said: "Much fun with a €" 15 | More unicode† 16 | JABBERWOCKY 17 | 18 | Lewis Carroll 19 | 20 | (from Through the Looking-Glass and What Alice Found There, 1872) 21 | `Twas brillig, and the slithy toves 22 | Did gyre and gimble in the wabe: 23 | All mimsy were the borogoves, 24 | And the mome raths outgrabe. 25 | 26 | 27 | 28 | "Beware the Jabberwock, my son! 29 | The jaws that bite, the claws that catch! 30 | Beware the Jubjub bird, and shun 31 | The frumious Bandersnatch!" 32 | He took his vorpal sword in hand: 33 | Long time the manxome foe he sought -- 34 | So rested he by the Tumtum tree, 35 | And stood awhile in thought. 36 | And, as in uffish thought he stood, 37 | The Jabberwock, with eyes of flame, 38 | Came whiffling through the tulgey wood, 39 | And burbled as it came! 40 | One, two! One, two! And through and through 41 | The vorpal blade went snicker-snack! 42 | He left it dead, and with its head 43 | He went galumphing back. 44 | "And, has thou slain the Jabberwock? 45 | Come to my arms, my beamish boy! 46 | O frabjous day! Callooh! Callay!' 47 | He chortled in his joy. 48 | 49 | 50 | 51 | `Twas brillig, and the slithy toves 52 | Did gyre and gimble in the wabe; 53 | All mimsy were the borogoves, 54 | And the mome raths outgrabe. 55 | 56 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .DELETE_ON_ERROR: 2 | 3 | ############ 4 | ## Verbosity 5 | ifeq ($(VERBOSE),1) 6 | Q = 7 | else 8 | Q = @ 9 | endif 10 | 11 | ############ 12 | ## Constants 13 | REVISION := $(shell svn info | grep Revision: | cut -d ' ' -f2) 14 | REVISION := $(strip $(if $(REVISION), $(REVISION), $(shell date '+%Y%m%d'))) 15 | UT_DIR := unittests 16 | RESULT_DIR := results 17 | XSLTPROC := xsltproc 18 | ECHO := /bin/echo 19 | DIFF := diff 20 | X2JSON := xml2json.xslt 21 | X2JS := xml2js.xslt 22 | BUILD_DIR := build/ 23 | PACKAGE_DIR := $(BUILD_DIR)/xml2json-xslt-r$(REVISION) 24 | PACKAGE := $(BUILD_DIR)/xml2json-xslt-r$(REVISION).zip 25 | 26 | .PHONY: default 27 | default: alltests 28 | 29 | ############### 30 | ## Dist Targets 31 | TARGETS := $(PACKAGE_DIR)/xml2json.xslt \ 32 | $(PACKAGE_DIR)/xml2js.xslt \ 33 | $(PACKAGE_DIR)/COPYRIGHT \ 34 | $(PACKAGE_DIR)/README 35 | 36 | .PHONY: build 37 | build: $(TARGETS) 38 | 39 | $(PACKAGE_DIR)/%: % $(PACKAGE_DIR)/.stamp $(TESTS) 40 | $(Q)cp $< $@ 41 | 42 | ########## 43 | ## Package 44 | $(PACKAGE): $(TARGETS) $(TESTS) 45 | $(Q)cd $(BUILD_DIR) && zip -q -9 -r $(notdir $(PACKAGE)) $(notdir $(PACKAGE_DIR)) -x $(notdir $(PACKAGE_DIR))/.stamp 46 | 47 | .PHONY: package 48 | package: $(PACKAGE) 49 | 50 | ############### 51 | ## Test Targets 52 | JSON_TESTS := $(patsubst $(UT_DIR)/%.json.expected, $(RESULT_DIR)/%.json.passed, $(wildcard $(UT_DIR)/*.json.expected)) 53 | JS_TESTS := $(patsubst $(UT_DIR)/%.js.expected, $(RESULT_DIR)/%.js.passed, $(wildcard $(UT_DIR)/*.js.expected)) 54 | 55 | TESTS := $(JSON_TESTS) $(JS_TESTS) 56 | OUTPUTS := $(patsubst %.passed,%.output,$(TESTS)) 57 | # Outputs are intermediate files, but should be saved if 58 | # the unittests failed. 59 | .SECONDARY: $(OUTPUTS) 60 | 61 | .PHONY: alltests 62 | alltests: 63 | $(Q)-$(MAKE) -k clean tests VERBOSE=$(VERBOSE) 64 | $(Q)$(ECHO) 65 | $(Q)$(ECHO) " ** Results:" 66 | $(Q)$(ECHO) " ** -----------" 67 | $(Q)$(ECHO) -n " ** Passed: " 68 | $(Q)ls -1 $(RESULT_DIR)/*.passed | wc -l 69 | $(Q)$(ECHO) -n " ** Failed: " 70 | $(Q)ls -1 $(RESULT_DIR)/*.failed | wc -l 71 | 72 | .PHONY: tests 73 | tests: $(TESTS) 74 | $(info All tests passed!) 75 | 76 | %/.stamp: 77 | $(Q)mkdir -p $(@D) 78 | $(Q)touch $@ 79 | 80 | $(RESULT_DIR)/%.json.passed: $(RESULT_DIR)/%.json.output $(UT_DIR)/%.json.expected 81 | $(Q)$(DIFF) -u $^ > $(RESULT_DIR)/$*.json.failed 82 | $(Q)mv $(RESULT_DIR)/$*.json.failed $@ 83 | # Don't save the output if it passed. 84 | $(Q)rm $(RESULT_DIR)/$*.json.output 85 | 86 | $(RESULT_DIR)/%.js.passed: $(RESULT_DIR)/%.js.output $(UT_DIR)/%.js.expected 87 | $(Q)$(DIFF) -u $^ > $(RESULT_DIR)/$*.js.failed 88 | $(Q)mv $(RESULT_DIR)/$*.js.failed $@ 89 | # Don't save the output if it passed. 90 | $(Q)rm $(RESULT_DIR)/$*.js.output 91 | 92 | $(RESULT_DIR)/%.json.output: $(UT_DIR)/%.xml $(RESULT_DIR)/.stamp 93 | $(Q)$(XSLTPROC) $(X2JSON) $(filter %.xml, $^) > $@ 94 | $(Q)perl -pi -e 's!\n?$$!\n!' $@ 95 | 96 | $(RESULT_DIR)/%.js.output: $(UT_DIR)/%.xml $(RESULT_DIR)/.stamp 97 | $(Q)$(XSLTPROC) $(X2JS) $(filter %.xml, $^) > $@ 98 | $(Q)perl -pi -e 's!\n?$$!\n!' $@ 99 | 100 | .PHONY: clean 101 | clean: 102 | $(Q)rm -rf $(RESULT_DIR) $(BUILD_DIR) 103 | -------------------------------------------------------------------------------- /xml2json.xslt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 27 | 28 | 29 | 30 | 31 | 0123456789 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 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 | 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 | 126 | 127 | 128 | 129 | 130 | true 131 | false 132 | 133 | 134 | 135 | { 136 | 137 | 138 | 139 | : 140 | 141 | 142 | 143 | null 144 | 145 | 146 | 147 | 148 | 149 | 150 | , 151 | } 152 | 153 | 154 | 155 | 156 | [ 157 | 158 | 159 | null 160 | 161 | 162 | 163 | 164 | 165 | , 166 | ] 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | -------------------------------------------------------------------------------- /xml2js.xslt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 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 | 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 | 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 | 206 | 207 | 208 | 209 | 210 | true 211 | false 212 | 213 | 214 | 221 | new Date( 222 | 223 | , 224 | 225 | -1, 226 | 227 | ) 228 | 229 | 230 | 241 | new Date( 242 | 243 | , 244 | 245 | -1, 246 | 247 | , 248 | 249 | , 250 | 251 | ) 252 | 253 | 254 | 267 | new Date( 268 | 269 | , 270 | 271 | -1, 272 | 273 | , 274 | 275 | , 276 | 277 | , 278 | 279 | ) 280 | 281 | 282 | 283 | 284 | { 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | : 294 | 295 | 296 | 297 | null 298 | 299 | 300 | 301 | 302 | 303 | 304 | , 305 | } 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | [ 326 | 327 | 328 | 329 | null 330 | 331 | 332 | 333 | 334 | 335 | , 336 | ] 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | /**/ 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | --------------------------------------------------------------------------------