├── test ├── utf16.xml ├── issue3.xml ├── invalid.xml ├── issue3.json ├── version1-1.xml ├── xml-rpc.xml ├── issue4.xml ├── issue9.xsd ├── control.invalid.xml ├── entity.invalid.xml ├── hexentity.invalid.xml ├── dtd.xml ├── entities.pull.xml ├── soap.xml ├── address.json ├── issue12.xsd ├── coerceTypes.xml ├── issue4.json ├── valueProperty.xml ├── issue12b.xsd ├── address.xml ├── rss.xml ├── badge.svg ├── bookstore.json ├── bookstore.xml ├── example.xhtml ├── addressSchema.xsd ├── shiporderSchema.xsd ├── word.xml ├── xbrl.xml ├── sample.wsdl ├── purchaseorder.xsd ├── structure.invalid.xml ├── pc_hd_abr_v2_dash_master.coerceTypes.noap.mpd ├── web.config ├── c4atom_noap.coerceTypes.xml ├── atomSchema.xsd └── mpd-dash.xsd ├── out ├── fragment1.xml ├── bookstore.jpath ├── issue3.xml ├── issue3.json ├── soap.json ├── issue4.xml ├── address.xml ├── coerceTypes.json ├── issue12.json ├── issue4.json ├── issue12b.json ├── address.json ├── issue9.json ├── rss.json ├── bookstore.json ├── bookstore.xml ├── addressSchema.json ├── valueProperty.json ├── example.json ├── badge.json ├── shiporderSchema.json ├── word.json ├── sample.json ├── purchaseorder.json ├── pc_hd_abr_v2_dash_master.coerceTypes.noap.json ├── c4atom_noap.coerceTypes.json └── atomSchema.json ├── .editorconfig ├── common.js ├── examples ├── fragment.js ├── pushparser.js ├── pullparser.js ├── jsont.js ├── xml2xml.js └── jpath.js ├── .github └── workflows │ └── ci.yaml ├── cli ├── xml2json.js ├── json2xml.js └── xsd2json.js ├── .gitignore ├── .npmignore ├── package.json ├── json2xml.js ├── LICENSE ├── jsont.js ├── README.md ├── xmlWrite.js ├── xml2json.js ├── jpath.js ├── testRunner.js └── jgeXml.js /test/utf16.xml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mermade/jgeXml/HEAD/test/utf16.xml -------------------------------------------------------------------------------- /out/fragment1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | baz 5 | -------------------------------------------------------------------------------- /out/bookstore.jpath: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "query": "$.store.book[2].price", 4 | "fetch": "store.book[2].price", 5 | "expected": "8.99" 6 | } 7 | ] -------------------------------------------------------------------------------- /test/issue3.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 |
H1
4 | B1 5 |
H2
6 | B2 7 |
-------------------------------------------------------------------------------- /test/invalid.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Ref=some here 5 | 6 | 7 | -------------------------------------------------------------------------------- /out/issue3.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 |
H1
4 |
H2
5 | B1 6 | B2 7 |
-------------------------------------------------------------------------------- /out/issue3.json: -------------------------------------------------------------------------------- 1 | { 2 | "root": { 3 | "header": [ 4 | "H1", 5 | "H2" 6 | ], 7 | "body": [ 8 | "B1", 9 | "B2" 10 | ] 11 | } 12 | } -------------------------------------------------------------------------------- /test/issue3.json: -------------------------------------------------------------------------------- 1 | { 2 | "root": { 3 | "header": [ 4 | "H1", 5 | "H2" 6 | ], 7 | "body": [ 8 | "B1", 9 | "B2" 10 | ] 11 | } 12 | } -------------------------------------------------------------------------------- /test/version1-1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 1 6 | 7 | -------------------------------------------------------------------------------- /test/xml-rpc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | examples.getStateName 4 | 5 | 6 | 40 7 | 8 | 9 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = lf 5 | indent_style = space 6 | indent_size = 4 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false 13 | -------------------------------------------------------------------------------- /test/issue4.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Foligno Madonna, by Raphael 4 | This is Raphael's 'Foligno' Madonna, painted in 5 | 1511-1512. 6 | -------------------------------------------------------------------------------- /common.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(String.prototype,'replaceAll',{ 4 | value: function(search, replacement) { 5 | var target = this; 6 | return target.split(search).join(replacement); 7 | }, 8 | enumerable: false} 9 | ); 10 | 11 | -------------------------------------------------------------------------------- /test/issue9.xsd: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /out/soap.json: -------------------------------------------------------------------------------- 1 | { 2 | "soap:Envelope": { 3 | "@xmlns:soap": "http://www.w3.org/2003/05/soap-envelope", 4 | "soap:Header": {}, 5 | "soap:Body": { 6 | "m:GetStockPrice": { 7 | "@xmlns:m": "http://www.example.org/stock/Surya", 8 | "m:StockName": "IBM" 9 | } 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /test/control.invalid.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | dataval1 5 | dataval2 6 | 7 | 8 | 3 9 | dataval4 10 | 11 | -------------------------------------------------------------------------------- /test/entity.invalid.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | dataval1 5 | dataval2 6 | 7 | 8 | 3 9 | dataval4 10 | 11 | -------------------------------------------------------------------------------- /test/hexentity.invalid.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | dataval1 5 | dataval 2 6 | 7 | 8 | 3 9 | dataval4 10 | 11 | -------------------------------------------------------------------------------- /test/dtd.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 9 | 10 | 11 | 12 | ]> 13 | 14 | Hello World. -------------------------------------------------------------------------------- /test/entities.pull.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | dataval1 5 | dataval 2 6 | 7 | 8 | 3 9 | dataval4 10 | 11 | 12 | -------------------------------------------------------------------------------- /test/soap.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | IBM 8 | 9 | 10 | -------------------------------------------------------------------------------- /out/issue4.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Foligno Madonna, by Raphael 4 | 5 | <#text>This is Raphael's 'Foligno' Madonna, painted in 6 | <#text>- 7 | <#text>. 8 | 1511 9 | 1512 10 | 11 | -------------------------------------------------------------------------------- /test/address.json: -------------------------------------------------------------------------------- 1 | { 2 | "Address": { 3 | "@xmlns:xsi": "http://www.w3.org/2001/XMLSchema-instance", 4 | "@xsi:noNamespaceSchemaLocation": "SimpleAddress.xsd", 5 | "Recipient": "Mr. Walter C. Brown", 6 | "House": "49", 7 | "Street": "Featherstone Street", 8 | "Town": "LONDON", 9 | "PostCode": "EC1Y 8SY", 10 | "Country": "UK" 11 | } 12 | } -------------------------------------------------------------------------------- /test/issue12.xsd: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /out/address.xml: -------------------------------------------------------------------------------- 1 | 2 |
3 | Mr. Walter C. Brown 4 | 49 5 | Featherstone Street 6 | LONDON 7 | EC1Y 8SY 8 | UK 9 |
-------------------------------------------------------------------------------- /out/coerceTypes.json: -------------------------------------------------------------------------------- 1 | { 2 | "Tests": { 3 | "quoting": [ 4 | { 5 | "data": "string" 6 | }, 7 | { 8 | "data": 1 9 | }, 10 | { 11 | "data": 2 12 | }, 13 | { 14 | "data": 2.5 15 | }, 16 | { 17 | "data": true 18 | }, 19 | { 20 | "data": {} 21 | } 22 | ] 23 | } 24 | } -------------------------------------------------------------------------------- /test/coerceTypes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | string 5 | 6 | 7 | 1 8 | 9 | 10 | 2 11 | 12 | 13 | 2.5 14 | 15 | 16 | true 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /out/issue12.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "test/issue12.xsd", 3 | "$schema": "http://json-schema.org/schema#", 4 | "type": "object", 5 | "properties": { 6 | "DateType1Code": { 7 | "type": "string", 8 | "enum": [ 9 | "UKWN" 10 | ] 11 | } 12 | }, 13 | "required": [ 14 | "Address", 15 | "DateType1Code" 16 | ], 17 | "additionalProperties": false 18 | } 19 | -------------------------------------------------------------------------------- /out/issue4.json: -------------------------------------------------------------------------------- 1 | { 2 | "painting": { 3 | "img": { 4 | "@src": "madonna.jpg", 5 | "@alt": "Foligno Madonna, by Raphael" 6 | }, 7 | "caption": { 8 | "#text": [ 9 | "This is Raphael's 'Foligno' Madonna, painted in", 10 | "-", 11 | "." 12 | ], 13 | "date": [ 14 | "1511", 15 | "1512" 16 | ] 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /test/issue4.json: -------------------------------------------------------------------------------- 1 | { 2 | "painting": { 3 | "img": { 4 | "@src": "madonna.jpg", 5 | "@alt": "Foligno Madonna, by Raphael" 6 | }, 7 | "caption": { 8 | "#text": [ 9 | "This is Raphael's 'Foligno' Madonna, painted in", 10 | "-", 11 | "." 12 | ], 13 | "date": [ 14 | "1511", 15 | "1512" 16 | ] 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /test/valueProperty.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | sibling1 5 | sibling2 6 | 7 | 8 | sibling3 9 | sibling4 10 | 11 | -------------------------------------------------------------------------------- /examples/fragment.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var xw = require('../xmlWrite'); 4 | 5 | xw.startFragment(2); 6 | xw.docType('fubar'); 7 | xw.startElement('foo'); 8 | xw.processingInstruction('nitfol xyzzy'); 9 | xw.startElement('bar'); 10 | xw.comment('potrzebie'); 11 | xw.content('baz'); 12 | xw.cdata('snafu'); 13 | xw.endElement('bar'); 14 | xw.endElement('foo'); 15 | 16 | console.log(xw.endFragment()); 17 | -------------------------------------------------------------------------------- /test/issue12b.xsd: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /out/issue12b.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "test/issue12b.xsd", 3 | "$schema": "http://json-schema.org/schema#", 4 | "type": "object", 5 | "properties": { 6 | "DateType1Code": { 7 | "type": "string", 8 | "enum": [ 9 | "UKWN", 10 | "VAL2" 11 | ] 12 | } 13 | }, 14 | "required": [ 15 | "Address", 16 | "DateType1Code" 17 | ], 18 | "additionalProperties": false 19 | } 20 | -------------------------------------------------------------------------------- /out/address.json: -------------------------------------------------------------------------------- 1 | { 2 | "Address": { 3 | "@xmlns:xsi": "http://www.w3.org/2001/XMLSchema-instance", 4 | "@xsi:noNamespaceSchemaLocation": "SimpleAddress.xsd", 5 | "Recipient": "Mr. Walter C. Brown", 6 | "House": { 7 | "#text": [ 8 | "49", 9 | "A" 10 | ] 11 | }, 12 | "Street": "Featherstone Street", 13 | "Town": "LONDON", 14 | "PostCode": "EC1Y 8SY", 15 | "#text": "Customer123", 16 | "Country": "UK" 17 | } 18 | } -------------------------------------------------------------------------------- /out/issue9.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "test/issue9.xsd", 3 | "$schema": "http://json-schema.org/schema#", 4 | "type": "object", 5 | "properties": { 6 | "test": { 7 | "properties": { 8 | "id": { 9 | "type": "string", 10 | "enum": [ 11 | "123" 12 | ] 13 | } 14 | }, 15 | "additionalProperties": false, 16 | "type": "object" 17 | } 18 | }, 19 | "required": [ 20 | "test" 21 | ], 22 | "additionalProperties": false 23 | } 24 | -------------------------------------------------------------------------------- /.github/workflows/ci.yaml: -------------------------------------------------------------------------------- 1 | name: ci 2 | 3 | on: 4 | push: 5 | branches: [ 'main' ] 6 | pull_request: 7 | branches: [ 'main' ] 8 | 9 | jobs: 10 | test: 11 | runs-on: ubuntu-latest 12 | 13 | strategy: 14 | matrix: 15 | node-version: [12, 14, 16] 16 | 17 | steps: 18 | - uses: actions/checkout@v2 19 | - name: Set up node 20 | uses: actions/setup-node@v1 21 | with: 22 | node-version: ${{ matrix.node-version }} 23 | 24 | - run: npm i 25 | # - run: npm run lint 26 | - run: npm run test 27 | 28 | -------------------------------------------------------------------------------- /test/address.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
6 | 7 | Mr. Walter C. Brown 8 | 49A 9 | Featherstone Street 10 | LONDON 11 | EC1Y 8SY 12 | 13 | UK 14 |
-------------------------------------------------------------------------------- /test/rss.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Example Channel 5 | http://example.com/ 6 | My example channel 7 | 8 | News for September the Second 9 | http://example.com/2002/09/01 10 | other things happened today 11 | 12 | 13 | News for September the First 14 | http://example.com/2002/09/02 15 | 16 | 17 | -------------------------------------------------------------------------------- /out/rss.json: -------------------------------------------------------------------------------- 1 | { 2 | "rss": { 3 | "@version": "2.0", 4 | "channel": { 5 | "title": "Example Channel", 6 | "link": "http://example.com/", 7 | "description": "My example channel", 8 | "item": [ 9 | { 10 | "title": "News for September the Second", 11 | "link": "http://example.com/2002/09/01", 12 | "description": "other things happened today" 13 | }, 14 | { 15 | "title": "News for September the First", 16 | "link": "http://example.com/2002/09/02" 17 | } 18 | ] 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /cli/xml2json.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 'use strict'; 3 | 4 | var fs = require('fs'); 5 | var x2j = require('../xml2json'); 6 | 7 | var filename = process.argv[2]; 8 | if (!filename) { 9 | console.warn('Usage: xml2json {infile}'); 10 | process.exit(1); 11 | } 12 | var valueProperty = false; 13 | var coerceTypes = false; 14 | 15 | if (process.argv.length>3) { 16 | valueProperty = (process.argv[3] != '0'); 17 | } 18 | if (process.argv.length>4) { 19 | coerceTypes = (process.argv[4] != '0'); 20 | } 21 | 22 | var xml = fs.readFileSync(filename,'utf8'); 23 | 24 | var obj = x2j.xml2json(xml,{"attributePrefix": "@","valueProperty": valueProperty, "coerceTypes": coerceTypes}); 25 | console.log(JSON.stringify(obj,null,2)); 26 | -------------------------------------------------------------------------------- /cli/json2xml.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 'use strict'; 3 | 4 | var fs = require('fs'); 5 | var j2x = require('../json2xml'); 6 | 7 | var filename = process.argv[2]; 8 | if (!filename) { 9 | console.warn('Usage: json2xml {infile}'); 10 | process.exit(1); 11 | } 12 | var indent = 2; 13 | var indentStr = ' '; 14 | 15 | if (process.argv.length>3) { 16 | indent = 1; 17 | indentStr = '\t'; 18 | } 19 | 20 | var json = fs.readFileSync(filename,'utf8'); 21 | 22 | var obj = {}; 23 | try { 24 | obj = JSON.parse(json); 25 | } 26 | catch (err) { 27 | console.error('That is not valid JSON'); 28 | console.error(err); 29 | process.exit(1); 30 | } 31 | 32 | var xml = j2x.getXml(obj,'@','',indent,indentStr,false); 33 | console.log(xml); 34 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | package-lock.json 2 | test/nitro-schema.xsd 3 | out/nitro-schema.json 4 | 5 | in/ 6 | .vscode/ 7 | 8 | # Logs 9 | logs 10 | *.log 11 | 12 | # Runtime data 13 | pids 14 | *.pid 15 | *.seed 16 | 17 | # Directory for instrumented libs generated by jscoverage/JSCover 18 | lib-cov 19 | 20 | # Coverage directory used by tools like istanbul 21 | coverage 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # node-waf configuration 27 | .lock-wscript 28 | 29 | # Compiled binary addons (http://nodejs.org/api/addons.html) 30 | build/Release 31 | 32 | # Dependency directory 33 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git 34 | node_modules 35 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | test/ 2 | in/ 3 | out/ 4 | .vscode/ 5 | old/ 6 | musicxml/ 7 | xmlbible/ 8 | doc/ 9 | ideas/ 10 | temp/ 11 | 12 | # Logs 13 | logs 14 | *.log 15 | 16 | # Runtime data 17 | pids 18 | *.pid 19 | *.seed 20 | 21 | # Directory for instrumented libs generated by jscoverage/JSCover 22 | lib-cov 23 | 24 | # Coverage directory used by tools like istanbul 25 | coverage 26 | 27 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 28 | .grunt 29 | 30 | # node-waf configuration 31 | .lock-wscript 32 | 33 | # Compiled binary addons (http://nodejs.org/api/addons.html) 34 | build/Release 35 | 36 | # Dependency directory 37 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git 38 | node_modules 39 | -------------------------------------------------------------------------------- /examples/pushparser.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var fs = require('fs'); 4 | var jgeXml = require('../jgeXml.js'); 5 | 6 | var filename = process.argv[2]; 7 | if (!filename) { 8 | console.warn('Usage: pushparser {infile} [encoding]'); 9 | process.exit(1); 10 | } 11 | var encoding = 'utf8'; 12 | if (process.argv.length>3) encoding = process.argv[3]; 13 | 14 | var xml = fs.readFileSync(filename,encoding); 15 | console.log(xml); 16 | console.log(); 17 | 18 | var depth = 0; 19 | 20 | var result = jgeXml.parse(xml,function(state,token){ 21 | if (state == jgeXml.sElement) { 22 | depth++; 23 | } 24 | else if (state == jgeXml.sEndElement) { 25 | depth--; 26 | } 27 | console.log(jgeXml.getStateName(state)+' '+depth+' "'+token+'"'); 28 | }); 29 | console.log(result); 30 | if (!result) process.exitCode = 1; 31 | -------------------------------------------------------------------------------- /test/badge.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | XMLXML 14 | VALIDVALID 15 | 16 | -------------------------------------------------------------------------------- /test/bookstore.json: -------------------------------------------------------------------------------- 1 | { "store": { 2 | "book": [ 3 | { "category": "reference", 4 | "author": "Nigel Rees", 5 | "title": "Sayings of the Century", 6 | "price": 8.95 7 | }, 8 | { "category": "fiction", 9 | "author": "Evelyn Waugh", 10 | "title": "Sword of Honour", 11 | "price": 12.99 12 | }, 13 | { "category": "fiction", 14 | "author": "Herman Melville", 15 | "title": "Moby Dick", 16 | "isbn": "0-553-21311-3", 17 | "price": 8.99 18 | }, 19 | { "category": "fiction", 20 | "author": "J. R. R. Tolkien", 21 | "title": "The Lord of the Rings", 22 | "isbn": "0-395-19395-8", 23 | "price": 22.99 24 | } 25 | ], 26 | "bicycle": { 27 | "color": "red", 28 | "price": 19.95 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /test/bookstore.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | reference 5 | Nigel Rees 6 | Sayings of the Century 7 | 8.95 8 | 9 | 10 | fiction 11 | Evelyn Waugh 12 | Sword of Honour 13 | 12.99 14 | 15 | 16 | fiction 17 | Herman Melville 18 | Moby Dick 19 | 0-553-21311-3 20 | 8.99 21 | 22 | 23 | fiction 24 | J. R. R. Tolkien 25 | The Lord of the Rings 26 | 0-395-19395-8 27 | 22.99 28 | 29 | 30 | red 31 | 19.95 32 | 33 | -------------------------------------------------------------------------------- /out/bookstore.json: -------------------------------------------------------------------------------- 1 | { 2 | "store": { 3 | "book": [ 4 | { 5 | "category": "reference", 6 | "author": "Nigel Rees", 7 | "title": "Sayings of the Century", 8 | "price": "8.95" 9 | }, 10 | { 11 | "category": "fiction", 12 | "author": "Evelyn Waugh", 13 | "title": "Sword of Honour", 14 | "price": "12.99" 15 | }, 16 | { 17 | "category": "fiction", 18 | "author": "Herman Melville", 19 | "title": "Moby Dick", 20 | "isbn": "0-553-21311-3", 21 | "price": "8.99" 22 | }, 23 | { 24 | "category": "fiction", 25 | "author": "J. R. R. Tolkien", 26 | "title": "The Lord of the Rings", 27 | "isbn": "0-395-19395-8", 28 | "price": "22.99" 29 | } 30 | ], 31 | "bicycle": { 32 | "color": "red", 33 | "price": "19.95" 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /out/bookstore.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | reference 5 | Nigel Rees 6 | Sayings of the Century 7 | 8.95 8 | 9 | 10 | fiction 11 | Evelyn Waugh 12 | Sword of Honour 13 | 12.99 14 | 15 | 16 | fiction 17 | Herman Melville 18 | Moby Dick 19 | 0-553-21311-3 20 | 8.99 21 | 22 | 23 | fiction 24 | J. R. R. Tolkien 25 | The Lord of the Rings 26 | 0-395-19395-8 27 | 22.99 28 | 29 | 30 | red 31 | 19.95 32 | 33 | -------------------------------------------------------------------------------- /test/example.xhtml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | XHTML 1.0 Strict Example 7 | 10 | 11 | 12 |

This is an example of an 13 | XHTML 1.0 Strict document.
14 | Valid XHTML 1.0 Strict
17 | 22 |

23 | 24 | -------------------------------------------------------------------------------- /examples/pullparser.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var fs = require('fs'); 4 | var jgeXml = require('../jgeXml.js'); 5 | 6 | var filename = process.argv[2]; 7 | if (!filename) { 8 | console.warn('Usage: pullparser {infile} [encoding]'); 9 | process.exit(1); 10 | } 11 | var encoding = 'utf8'; 12 | if (process.argv.length>3) encoding = process.argv[3]; 13 | 14 | var xml = fs.readFileSync(filename,encoding); 15 | console.log(xml); 16 | console.log(); 17 | 18 | var context = {}; 19 | var depth = 0; 20 | 21 | while (!context.state || context.state != jgeXml.sEndDocument) { 22 | context = jgeXml.parse(xml,null,context); 23 | if (context.state == jgeXml.sElement) { 24 | depth++; 25 | } 26 | else if (context.state == jgeXml.sEndElement) { 27 | depth--; 28 | } 29 | console.log(jgeXml.getStateName(context.state)+' '+context.position+' '+depth+' '+context.depth+' "'+context.token+'"'); 30 | } 31 | console.log(context.wellFormed); 32 | if (!context.wellFormed) process.exitCode = 1; 33 | -------------------------------------------------------------------------------- /cli/xsd2json.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 'use strict'; 3 | 4 | var fs = require('fs'); 5 | var x2j = require('../xml2json'); 6 | var xsd = require('../xsd2json'); 7 | 8 | var filename = process.argv[2]; 9 | if (!filename) { 10 | console.warn('Usage: xsd2json {infile} [{outfile}]'); 11 | process.exit(1); 12 | } 13 | var valueProperty = false; 14 | 15 | var xml = fs.readFileSync(filename,'utf8'); 16 | 17 | try { 18 | var obj = x2j.xml2json(xml,{"attributePrefix": "@","valueProperty": valueProperty, "coerceTypes": false}); 19 | } 20 | catch (err) { 21 | console.error('That is not valid JSON'); 22 | console.error(err); 23 | console.log(x2j.getString()); 24 | process.exit(1); 25 | } 26 | 27 | var laxUris = (filename.indexOf('.lax')>=0); 28 | var json = xsd.getJsonSchema(obj,filename,'',laxUris,'xs:'); 29 | 30 | if (process.argv.length>3) { 31 | var outfile = process.argv[3]; 32 | fs.writeFileSync(outfile,JSON.stringify(json,null,2),'utf8'); 33 | } 34 | else { 35 | console.log(JSON.stringify(json,null,2)); 36 | } 37 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jgexml", 3 | "version": "0.4.3", 4 | "description": "The Just-Good-Enough XML Toolkit", 5 | "main": "jgeXml.js", 6 | "bin": { 7 | "xml2json": "./cli/xml2json.js", 8 | "json2xml": "./cli/json2xml.js", 9 | "xsd2json": "./cli/xsd2json.js" 10 | }, 11 | "scripts": { 12 | "test": "node testRunner", 13 | "cover": "npx istanbul cover testRunner.js" 14 | }, 15 | "repository": { 16 | "type": "git", 17 | "url": "git+https://github.com/Mermade/jgeXml.git" 18 | }, 19 | "keywords": [ 20 | "xml", 21 | "javascript", 22 | "json", 23 | "jsonpath", 24 | "jsont", 25 | "parser", 26 | "pullparser", 27 | "pullparsing", 28 | "pushparser", 29 | "pushparsing", 30 | "sax", 31 | "stax", 32 | "schema", 33 | "xsd" 34 | ], 35 | "author": "Mike Ralphson", 36 | "license": "BSD-3-Clause", 37 | "bugs": { 38 | "url": "https://github.com/Mermade/jgeXml/issues" 39 | }, 40 | "homepage": "https://github.com/Mermade/jgeXml#readme" 41 | } 42 | -------------------------------------------------------------------------------- /test/addressSchema.xsd: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /out/addressSchema.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "test/addressSchema.xsd", 3 | "$schema": "http://json-schema.org/schema#", 4 | "type": "object", 5 | "properties": { 6 | "Address": { 7 | "properties": { 8 | "Recipient": { 9 | "type": "string" 10 | }, 11 | "House": { 12 | "type": "string" 13 | }, 14 | "Street": { 15 | "type": "string" 16 | }, 17 | "Town": { 18 | "type": "string" 19 | }, 20 | "County": { 21 | "type": "string" 22 | }, 23 | "PostCode": { 24 | "type": "string" 25 | }, 26 | "Country": { 27 | "type": "string", 28 | "enum": [ 29 | "IN", 30 | "DE", 31 | "ES", 32 | "UK", 33 | "US" 34 | ] 35 | } 36 | }, 37 | "required": [ 38 | "Recipient", 39 | "House", 40 | "Street", 41 | "Town", 42 | "PostCode" 43 | ], 44 | "additionalProperties": false 45 | } 46 | }, 47 | "required": [ 48 | "Address" 49 | ], 50 | "additionalProperties": false 51 | } 52 | -------------------------------------------------------------------------------- /out/valueProperty.json: -------------------------------------------------------------------------------- 1 | { 2 | "test": [ 3 | { 4 | "element": [ 5 | { 6 | "@name": "parent1", 7 | "elementInner": [ 8 | { 9 | "@name": "child1", 10 | "#text": [ 11 | { 12 | "#value": "sibling1" 13 | } 14 | ] 15 | }, 16 | { 17 | "@name": "child2", 18 | "#text": [ 19 | { 20 | "#value": "sibling2" 21 | } 22 | ] 23 | } 24 | ] 25 | }, 26 | { 27 | "@name": "parent2", 28 | "elementInner": [ 29 | { 30 | "@name": "child1", 31 | "#text": [ 32 | { 33 | "#value": "sibling3" 34 | } 35 | ] 36 | }, 37 | { 38 | "@name": "child2", 39 | "#text": [ 40 | { 41 | "#value": "sibling4" 42 | } 43 | ] 44 | } 45 | ] 46 | } 47 | ] 48 | } 49 | ] 50 | } -------------------------------------------------------------------------------- /examples/jsont.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var jsont = require('../jsont'); 4 | 5 | function run(obj,rules) { 6 | console.log(); 7 | console.log(obj); 8 | console.log('+'); 9 | console.log(rules); 10 | console.log('='); 11 | console.log(jsont.transform(obj,rules)); 12 | } 13 | 14 | // see http://goessner.net/articles/jsont/ 15 | 16 | var obj = { "link": {"uri":"http://company.com", "title":"company homepage" }}; 17 | var rules = { "link": "{link.title}" }; 18 | run(obj,rules); 19 | 20 | obj = { "line": { "p1": {"x":2, "y":3}, 21 | "p2": {"x":4, "y":5} }}; 22 | rules = { "self": "{line}", 23 | "line": "" }; 25 | run(obj,rules); 26 | 27 | obj = ["red", "green", "blue"] 28 | rules = {"self": "
    \n{$}
", 29 | "self[*]": "
  • {$}
  • \n"}; 30 | run(obj,rules); 31 | 32 | obj = { "color": "blue", 33 | "closed": true, 34 | "points": [[10,10],[20,10],[20,20],[10,20]] }; 35 | rules = { "self": "<{closed} stroke=\"{color}\" points=\"{points}\" />"+ 36 | "", 37 | "closed": function(x){return x ? "polygon" : "polyline";}, 38 | "points[*][*]": "{$} " }; 39 | run(obj,rules); 40 | -------------------------------------------------------------------------------- /out/example.json: -------------------------------------------------------------------------------- 1 | { 2 | "html": { 3 | "@xmlns": "http://www.w3.org/1999/xhtml", 4 | "@xml:lang": "en", 5 | "head": { 6 | "title": "XHTML 1.0 Strict Example", 7 | "script": { 8 | "@type": "application/javascript", 9 | "#text": "function loadpdf() {document.getElementById(\"pdf-object\").src=\"http://www.w3.org/TR/xhtml1/xhtml1.pdf\";}" 10 | } 11 | }, 12 | "body": { 13 | "@onload": "loadpdf()", 14 | "p": { 15 | "#text": [ 16 | "This is an example of an", 17 | "1.0 Strict document." 18 | ], 19 | "abbr": { 20 | "@title": "Extensible HyperText Markup Language", 21 | "#text": "XHTML" 22 | }, 23 | "br": [ 24 | {}, 25 | {} 26 | ], 27 | "img": { 28 | "@id": "validation-icon", 29 | "@src": "http://www.w3.org/Icons/valid-xhtml10", 30 | "@alt": "Valid XHTML 1.0 Strict" 31 | }, 32 | "object": { 33 | "@id": "pdf-object", 34 | "@type": "application/pdf", 35 | "@data": "http://www.w3.org/TR/xhtml1/xhtml1.pdf", 36 | "@width": "100%", 37 | "@height": "500" 38 | } 39 | } 40 | } 41 | } 42 | } -------------------------------------------------------------------------------- /test/shiporderSchema.xsd: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /json2xml.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var xmlWrite = require('./xmlWrite'); 4 | 5 | function traverse(obj,parent,attributePrefix) { 6 | 7 | var result = []; 8 | 9 | var array = Array.isArray(obj); 10 | for (var key in obj) { 11 | // skip loop if the property is from prototype 12 | if (!obj.hasOwnProperty(key)) continue; 13 | 14 | var propArray = Array.isArray(obj[key]); 15 | var output = array ? parent : key; 16 | 17 | if (typeof obj[key] !== 'object'){ 18 | if (key.indexOf(attributePrefix) === 0) { 19 | xmlWrite.attribute(key.substring(1),obj[key]); 20 | } 21 | else { 22 | xmlWrite.startElement(output); 23 | xmlWrite.content(obj[key]); 24 | xmlWrite.endElement(output); 25 | } 26 | } 27 | else { 28 | if (!propArray) { 29 | xmlWrite.startElement(output); 30 | } 31 | traverse(obj[key],output,attributePrefix); 32 | if (!propArray) { 33 | xmlWrite.endElement(output); 34 | } 35 | } 36 | } 37 | return result; 38 | } 39 | 40 | module.exports = { 41 | // TODO convert this to an options object 42 | getXml : function(obj,attrPrefix,standalone,indent,indentStr,fragment) { 43 | var attributePrefix = (attrPrefix ? attrPrefix : '@'); 44 | if (fragment) { 45 | xmlWrite.startFragment(indent,indentStr); 46 | } 47 | else { 48 | xmlWrite.startDocument('UTF-8',standalone,indent,indentStr); 49 | } 50 | traverse(obj,'',attributePrefix); 51 | return xmlWrite.endDocument(); 52 | } 53 | }; -------------------------------------------------------------------------------- /examples/xml2xml.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var fs = require('fs'); 4 | var jgeXml = require('../jgeXml.js'); 5 | var xmlWrite = require('../xmlWrite.js'); 6 | 7 | function x2x(xml) { 8 | var attributeName = ''; 9 | 10 | jgeXml.parse(xml,function(state,token){ 11 | 12 | if (state == jgeXml.sDeclaration) { 13 | xmlWrite.startDocument('UTF-8','',2); 14 | } 15 | else if (state == jgeXml.sComment) { 16 | xmlWrite.comment(token); 17 | } 18 | else if (state == jgeXml.sProcessingInstruction) { 19 | xmlWrite.processingInstruction(token); 20 | } 21 | else if (state == jgeXml.sCData) { 22 | xmlWrite.cdata(token); 23 | } 24 | else if (state == jgeXml.sContent) { 25 | xmlWrite.content(token); 26 | } 27 | else if (state == jgeXml.sEndElement) { 28 | xmlWrite.endElement(token); 29 | } 30 | else if (state == jgeXml.sAttribute) { 31 | attributeName = token; 32 | } 33 | else if (state == jgeXml.sValue) { 34 | xmlWrite.attribute(attributeName,token); 35 | } 36 | else if (state == jgeXml.sElement) { 37 | xmlWrite.startElement(token); 38 | } 39 | }); 40 | return xmlWrite.endDocument(); 41 | } 42 | 43 | var filename = process.argv[2]; 44 | if (!filename) { 45 | console.warn('Usage: xml2xml {infile}'); 46 | process.exit(1); 47 | } 48 | 49 | var xml = fs.readFileSync(filename,'utf8'); 50 | 51 | var s1 = x2x(xml); // normalise declaration, spacing and empty elements etc 52 | var s2 = x2x(s1); // compare 53 | var same = (s1 == s2); 54 | if (!same) { 55 | console.warn(s1); 56 | process.exitCode = 1; 57 | } 58 | console.log(s2); 59 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016, Mike Ralphson 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of jgeXml nor the names of its 15 | contributors may be used to endorse or promote products derived from 16 | this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | 29 | -------------------------------------------------------------------------------- /test/word.xml: -------------------------------------------------------------------------------- 1 | 2 | Hello, world. -------------------------------------------------------------------------------- /jsont.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const jpath = require('./jpath'); 4 | 5 | function replaceAll(s, from, to) { 6 | return s.split(from).join(to); 7 | } 8 | 9 | function transform(obj,rules) { 10 | var objName = '$'; 11 | var isArray = false; 12 | 13 | for (var n in obj) { 14 | objName = n; 15 | break; 16 | } 17 | 18 | var arrRules = []; 19 | 20 | for (var r in rules) { 21 | var rule = {}; 22 | rule.rule = rules[r]; 23 | rule.ruleName = r; 24 | rule.processed = false; 25 | arrRules.push(rule); 26 | } 27 | 28 | for (var r=arrRules.length-1;r>=0;r--) { 29 | var inner = arrRules[r].rule; 30 | 31 | if (arrRules[r].ruleName.indexOf('[*]') > 0) { 32 | isArray = true; 33 | } 34 | 35 | for (var o in obj) { 36 | var newObjName = objName; 37 | if (isArray) { 38 | newObjName = o; 39 | } 40 | var elements; 41 | if (typeof inner === 'function') { 42 | if (o == arrRules[r].ruleName) { 43 | elements = [inner(obj[arrRules[r].ruleName])]; 44 | } 45 | else { 46 | elements = []; 47 | } 48 | } 49 | else { 50 | elements = inner.split(/[\{\}]+/); 51 | } 52 | 53 | for (var i=1;i0) { 68 | obj[newObjName] = elements.join(''); 69 | } 70 | if (!isArray) continue; 71 | } 72 | arrRules[r].processed = true; 73 | } 74 | if (Array.isArray(obj)) return obj[0] 75 | else return obj[objName]; 76 | } 77 | 78 | module.exports = { 79 | transform : transform 80 | }; 81 | -------------------------------------------------------------------------------- /out/badge.json: -------------------------------------------------------------------------------- 1 | { 2 | "svg": { 3 | "@xmlns": "http://www.w3.org/2000/svg", 4 | "@width": "121", 5 | "@height": "20", 6 | "linearGradient": { 7 | "@id": "b", 8 | "@x2": "0", 9 | "@y2": "100%", 10 | "stop": [ 11 | { 12 | "@offset": "0", 13 | "@stop-color": "#bbb", 14 | "@stop-opacity": ".1" 15 | }, 16 | { 17 | "@offset": "1", 18 | "@stop-opacity": ".1" 19 | } 20 | ] 21 | }, 22 | "mask": { 23 | "@id": "a", 24 | "rect": { 25 | "@width": "121", 26 | "@height": "20", 27 | "@rx": "3", 28 | "@fill": "#fff" 29 | } 30 | }, 31 | "g": [ 32 | { 33 | "@mask": "url(#a)", 34 | "path": [ 35 | { 36 | "@fill": "#555", 37 | "@d": "M0 0h87v20H0z" 38 | }, 39 | { 40 | "@fill": "#4c1", 41 | "@d": "M87 0h34v20H87z" 42 | }, 43 | { 44 | "@fill": "url(#b)", 45 | "@d": "M0 0h121v20H0z" 46 | } 47 | ] 48 | }, 49 | { 50 | "@fill": "#fff", 51 | "@text-anchor": "middle", 52 | "@font-family": "DejaVu Sans,Verdana,Geneva,sans-serif", 53 | "@font-size": "11", 54 | "text": [ 55 | { 56 | "@x": "43.5", 57 | "@y": "15", 58 | "@fill": "#010101", 59 | "@fill-opacity": ".3", 60 | "#text": "XML" 61 | }, 62 | { 63 | "@x": "43.5", 64 | "@y": "14", 65 | "#text": "XML" 66 | }, 67 | { 68 | "@x": "103", 69 | "@y": "15", 70 | "@fill": "#010101", 71 | "@fill-opacity": ".3", 72 | "#text": "VALID" 73 | }, 74 | { 75 | "@x": "103", 76 | "@y": "14", 77 | "#text": "VALID" 78 | } 79 | ] 80 | } 81 | ] 82 | } 83 | } -------------------------------------------------------------------------------- /test/xbrl.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | 10 | 11 | 38679000000 13 | 35996000000 15 | 870000000 17 | ... 18 | 10430000000 20 | 21 | 22 | ACME 23 | 24 | 25 | 2004-01-01 26 | 27 | 28 | 29 | 30 | ACME 31 | 32 | 33 | 2004-12-31 34 | 35 | 36 | 37 | 38 | ACME 39 | 40 | 41 | 2004-01-01 42 | 2004-12-31 43 | 44 | 45 | 46 | iso4217:EUR 47 | 48 | -------------------------------------------------------------------------------- /out/shiporderSchema.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "test/shiporderSchema.xsd", 3 | "$schema": "http://json-schema.org/schema#", 4 | "type": "object", 5 | "properties": { 6 | "shiporder": { 7 | "properties": { 8 | "orderperson": { 9 | "type": "string" 10 | }, 11 | "shipto": { 12 | "type": "object", 13 | "properties": { 14 | "name": { 15 | "type": "string" 16 | }, 17 | "address": { 18 | "type": "string" 19 | }, 20 | "city": { 21 | "type": "string" 22 | }, 23 | "country": { 24 | "type": "string" 25 | } 26 | }, 27 | "required": [ 28 | "name", 29 | "address", 30 | "city", 31 | "country" 32 | ], 33 | "additionalProperties": false 34 | }, 35 | "item": { 36 | "type": "array", 37 | "minItems": 1, 38 | "items": { 39 | "type": "object", 40 | "properties": { 41 | "title": { 42 | "type": "string" 43 | }, 44 | "note": { 45 | "type": "array", 46 | "items": { 47 | "type": "string" 48 | } 49 | }, 50 | "quantity": { 51 | "type": "integer", 52 | "minimum": 1 53 | }, 54 | "price": { 55 | "type": "number" 56 | } 57 | }, 58 | "required": [ 59 | "title", 60 | "quantity", 61 | "price" 62 | ], 63 | "additionalProperties": false 64 | } 65 | }, 66 | "orderid": { 67 | "type": "string" 68 | }, 69 | "invoiceid": { 70 | "type": "string" 71 | } 72 | }, 73 | "required": [ 74 | "orderperson", 75 | "shipto", 76 | "item", 77 | "orderid" 78 | ], 79 | "additionalProperties": false 80 | } 81 | }, 82 | "required": [ 83 | "shiporder" 84 | ], 85 | "additionalProperties": false 86 | } -------------------------------------------------------------------------------- /test/sample.wsdl: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | This is a sample WSDL 2.0 document. 10 | 11 | 12 | 13 | 14 | 17 | 18 | ... 19 | ... 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 35 | 36 | 37 | 38 | 39 | 43 | 44 | 45 | 46 | 47 | 48 | 51 | 54 | 55 | -------------------------------------------------------------------------------- /out/word.json: -------------------------------------------------------------------------------- 1 | { 2 | "w:document": { 3 | "@xmlns:wpc": "http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas", 4 | "@xmlns:mc": "http://schemas.openxmlformats.org/markup-compatibility/2006", 5 | "@xmlns:o": "urn:schemas-microsoft-com:office:office", 6 | "@xmlns:r": "http://schemas.openxmlformats.org/officeDocument/2006/relationships", 7 | "@xmlns:m": "http://schemas.openxmlformats.org/officeDocument/2006/math", 8 | "@xmlns:v": "urn:schemas-microsoft-com:vml", 9 | "@xmlns:wp14": "http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing", 10 | "@xmlns:wp": "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing", 11 | "@xmlns:w10": "urn:schemas-microsoft-com:office:word", 12 | "@xmlns:w": "http://schemas.openxmlformats.org/wordprocessingml/2006/main", 13 | "@xmlns:w14": "http://schemas.microsoft.com/office/word/2010/wordml", 14 | "@xmlns:w15": "http://schemas.microsoft.com/office/word/2012/wordml", 15 | "@xmlns:wpg": "http://schemas.microsoft.com/office/word/2010/wordprocessingGroup", 16 | "@xmlns:wpi": "http://schemas.microsoft.com/office/word/2010/wordprocessingInk", 17 | "@xmlns:wne": "http://schemas.microsoft.com/office/word/2006/wordml", 18 | "@xmlns:wps": "http://schemas.microsoft.com/office/word/2010/wordprocessingShape", 19 | "@mc:Ignorable": "w14 w15 wp14", 20 | "w:body": { 21 | "w:p": { 22 | "@w:rsidR": "00656562", 23 | "@w:rsidRDefault": "00B42A0D", 24 | "w:r": { 25 | "w:t": "Hello, world." 26 | }, 27 | "w:bookmarkStart": { 28 | "@w:id": "0", 29 | "@w:name": "_GoBack" 30 | }, 31 | "w:bookmarkEnd": { 32 | "@w:id": "0" 33 | } 34 | }, 35 | "w:sectPr": { 36 | "@w:rsidR": "00656562", 37 | "w:pgSz": { 38 | "@w:w": "11906", 39 | "@w:h": "16838" 40 | }, 41 | "w:pgMar": { 42 | "@w:top": "1440", 43 | "@w:right": "1440", 44 | "@w:bottom": "1440", 45 | "@w:left": "1440", 46 | "@w:header": "708", 47 | "@w:footer": "708", 48 | "@w:gutter": "0" 49 | }, 50 | "w:cols": { 51 | "@w:space": "708" 52 | }, 53 | "w:docGrid": { 54 | "@w:linePitch": "360" 55 | } 56 | } 57 | } 58 | } 59 | } -------------------------------------------------------------------------------- /test/purchaseorder.xsd: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Purchase order schema for Example.com. 6 | Copyright 2000 Example.com. All rights reserved. 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 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 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /out/sample.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": { 3 | "@xmlns": "http://www.w3.org/ns/wsdl", 4 | "@xmlns:tns": "http://www.tmsws.com/wsdl20sample", 5 | "@xmlns:whttp": "http://schemas.xmlsoap.org/wsdl/http/", 6 | "@xmlns:wsoap": "http://schemas.xmlsoap.org/wsdl/soap/", 7 | "@targetNamespace": "http://www.tmsws.com/wsdl20sample", 8 | "documentation": "This is a sample WSDL 2.0 document.", 9 | "types": { 10 | "xs:schema": { 11 | "@xmlns:xs": "http://www.w3.org/2001/XMLSchema", 12 | "@xmlns": "http://www.tmsws.com/wsdl20sample", 13 | "@targetNamespace": "http://www.example.com/wsdl20sample", 14 | "xs:element": [ 15 | { 16 | "@name": "request", 17 | "#text": "..." 18 | }, 19 | { 20 | "@name": "response", 21 | "#text": "..." 22 | } 23 | ] 24 | } 25 | }, 26 | "interface": { 27 | "@name": "Interface1", 28 | "fault": { 29 | "@name": "Error1", 30 | "@element": "tns:response" 31 | }, 32 | "operation": { 33 | "@name": "Get", 34 | "@pattern": "http://www.w3.org/ns/wsdl/in-out", 35 | "input": { 36 | "@messageLabel": "In", 37 | "@element": "tns:request" 38 | }, 39 | "output": { 40 | "@messageLabel": "Out", 41 | "@element": "tns:response" 42 | } 43 | } 44 | }, 45 | "binding": [ 46 | { 47 | "@name": "HttpBinding", 48 | "@interface": "tns:Interface1", 49 | "@type": "http://www.w3.org/ns/wsdl/http", 50 | "operation": { 51 | "@ref": "tns:Get", 52 | "@whttp:method": "GET" 53 | } 54 | }, 55 | { 56 | "@name": "SoapBinding", 57 | "@interface": "tns:Interface1", 58 | "@type": "http://www.w3.org/ns/wsdl/soap", 59 | "@wsoap:protocol": "http://www.w3.org/2003/05/soap/bindings/HTTP/", 60 | "@wsoap:mepDefault": "http://www.w3.org/2003/05/soap/mep/request-response", 61 | "operation": { 62 | "@ref": "tns:Get" 63 | } 64 | } 65 | ], 66 | "service": { 67 | "@name": "Service1", 68 | "@interface": "tns:Interface1", 69 | "endpoint": [ 70 | { 71 | "@name": "HttpEndpoint", 72 | "@binding": "tns:HttpBinding", 73 | "@address": "http://www.example.com/rest/" 74 | }, 75 | { 76 | "@name": "SoapEndpoint", 77 | "@binding": "tns:SoapBinding", 78 | "@address": "http://www.example.com/soap/" 79 | } 80 | ] 81 | } 82 | } 83 | } -------------------------------------------------------------------------------- /examples/jpath.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var fs = require('fs'); 4 | var path = require('path'); 5 | var x2j = require('../xml2json'); 6 | var jpath = require('../jpath'); 7 | 8 | function dumpResults(tree,query) { 9 | console.log(); 10 | console.log(query); 11 | var matches = jpath.select(tree,query); 12 | for (var m in matches) { 13 | console.log(matches[m].value ? matches[m].value : matches[m]); 14 | } 15 | return matches; 16 | } 17 | 18 | function testBookStore(tree) { 19 | console.log(); 20 | console.log('That looks like a bookstore!'); 21 | 22 | dumpResults(tree,'$..*'); 23 | dumpResults(tree,'*'); 24 | dumpResults(tree,'$.store.book[*].author'); 25 | dumpResults(tree,'$..author'); 26 | dumpResults(tree,'$.store.*'); 27 | dumpResults(tree,'$.store..price'); 28 | dumpResults(tree,'$..book[2]'); 29 | dumpResults(tree,'$..book[2].price'); 30 | dumpResults(tree,'$..bicycle.price'); 31 | dumpResults(tree,'$..bicycle.price^'); 32 | } 33 | 34 | function propTest(obj,path) { 35 | console.log(path+' = '+jpath.fetchFromObject(obj,path)) 36 | } 37 | 38 | function ptrTest(obj,path) { 39 | console.log(path+' = '+jpath.jptr(obj,path)) 40 | } 41 | 42 | function testProperties(obj) { 43 | console.log(); 44 | propTest(obj,'store.book[2].price'); 45 | ptrTest(obj,'/store/book/2/price'); 46 | jpath.jptr(obj,'/store/book/2/price',10.99); 47 | ptrTest(obj,'/store/book/2/price'); 48 | } 49 | 50 | var filename = process.argv[2] || path.resolve(__dirname,'../test/bookstore.json'); 51 | var valueProperty = false; 52 | if (process.argv.length>3) { 53 | valueProperty = true; 54 | } 55 | 56 | var xml = fs.readFileSync(filename,'utf8'); 57 | 58 | try { 59 | var obj = x2j.xml2json(xml,{"attributePrefix": "@","valueProperty": valueProperty, "coerceTypes": false}); 60 | } 61 | catch (err) { 62 | console.error('That is not valid JSON'); 63 | console.error(err); 64 | console.log(xml); 65 | console.log(); 66 | console.log(x2j.getString()); 67 | process.exit(1); 68 | } 69 | 70 | var tree = jpath.build(obj); 71 | // we could do a select('*') here but it's redundant unless we want the bracketed form 72 | for (var i in tree) { 73 | // log our jpath for every item 74 | console.log(tree[i].depth+' '+jpath.path(tree[i],false)+' = '+tree[i].value); 75 | } 76 | 77 | if (tree.length>0) { 78 | if (obj.store && obj.store.book) { 79 | testBookStore(tree); 80 | testProperties(obj); 81 | } 82 | else { 83 | // generic examples 84 | var first = jpath.path(tree[1]); 85 | var matches = jpath.select(tree,first); 86 | for (var m in matches) { 87 | console.log('First; select('+jpath.path(matches[m])+') = '+matches[m].value); 88 | } 89 | 90 | var last = tree[tree.length-1]; 91 | console.log('Last; select('+jpath.path(last,true)+',true) = '+last.value); 92 | console.log(last.prefix) 93 | 94 | var parents = jpath.select(tree,last.prefix); 95 | if (parents.length>0) { 96 | var value = parents[0].value; 97 | if (typeof(value) === 'object') { 98 | value = JSON.stringify(value,null,2); 99 | } 100 | console.log('select('+jpath.path(parents[0],true)+',true) = '+value); 101 | } 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /test/structure.invalid.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 9 | 13 | 14 | 19 | 20 | 25 | 26 | 31 | 32 | 37 | 38 | 43 | 44 | 49 | 50 | 55 | 60 | 61 | 66 | 71 | 72 | 77 | 78 | 83 | 84 | 85 | 86 | 91 | 92 |