diff --git a/index.js b/index.js index 0fb9901..8a52cc4 100644 --- a/index.js +++ b/index.js @@ -5,7 +5,9 @@ * Other functions are internals exposed for a potential API usage. */ +var fs = require('fs'); var xml2js = require('xml2js'); +var temp = require('temp').track(); var xsdInclusions = require('./lib/xsd-inclusions'); var xsdExtensions = require('./lib/xsd-extensions'); @@ -22,9 +24,18 @@ exports.xsd2json = function(filePath, callback) { var builder = new xml2js.Builder(); var xml = builder.buildObject(mergedSchema); - prologWrapper.xsd2jsonWrapper(xml, function(err, schema) { + temp.open('xsd2json2', function(err, info) { if (err) return callback(err); - callback(null, jsonProcessing.postProcessing(schema)); + + fs.write(info.fd, xml); + fs.close(info.fd, function(err) { + if (err) return callback(err); + + prologWrapper.xsd2jsonWrapper(info.path, function(err, schema) { + if (err) return callback(err); + callback(null, jsonProcessing.postProcessing(schema)); + }); + }); }); }); }; diff --git a/lib/prolog-wrapper.js b/lib/prolog-wrapper.js index 93b53bb..4c5a89c 100644 --- a/lib/prolog-wrapper.js +++ b/lib/prolog-wrapper.js @@ -5,13 +5,13 @@ var log = require('winston').loggers.get('xsd2json'); /** * Wrap the original xsd2json prolog programm in a function call * - * @param [string] xsd - The XSD schema as a string + * @param [string] xsd - The XSD schema filename * @param [function] callback - The callback will be run with and optional error and the JSON schema result as a string */ exports.xsd2jsonWrapper = function(xsd, callback) { log.debug('Spawn prolog xsd2json program'); //var swipl = spawn(); - var swipl = spawn('swipl', ['-q', '-f', '../prolog-xsd2json/cli.pl', '--'], { + var swipl = spawn('swipl', ['-q', '-f', '../prolog-xsd2json/cli', xsd], { cwd: __dirname }); @@ -36,6 +36,5 @@ exports.xsd2jsonWrapper = function(xsd, callback) { callback(null, result); }); - swipl.stdin.write(xsd); swipl.stdin.end(); }; \ No newline at end of file diff --git a/package.json b/package.json index b034f46..a70f60a 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "lodash": "^2.4.1", "lodash-deep": "^1.4.2", "request": "^2.47.0", + "temp": "^0.8.1", "winston": "^0.8.3", "xml2js": "^0.4.4" }, diff --git a/prolog-xsd2json/README.md b/prolog-xsd2json/README.md index fd1c54e..95598e4 100644 --- a/prolog-xsd2json/README.md +++ b/prolog-xsd2json/README.md @@ -1,6 +1,6 @@ # xsd2json -CHR module to translate an XML Schema into equivalent JSON Schema. +Prolog/CHR module to translate an XML Schema into equivalent JSON Schema. ## Installation @@ -8,9 +8,13 @@ All you need is [SWI-Prolog](http://www.swi-prolog.org/). See there for installa ## Usage -`xsd2json` provides a command line interface. You can use it via +`xsd2json` provides a command line interface. You can directly execute it via - swipl -q -f cli.pl -- < /path/to/your.xsd + ./cli /path/to/your.xsd + +or by calling swipl: + + swipl -q -f cli /path/to/your.xsd Unfortunately the command line version is way slower than using `xsd2json` programmatically. The `xsd2json.pl` module provides a predicate `xsd2json/2` which can be used to convert a given XSD file into the equivalent JSON Schema. Call it via `swipl -s xsd2json.pl` followed by diff --git a/prolog-xsd2json/cli b/prolog-xsd2json/cli new file mode 100755 index 0000000..bf06942 --- /dev/null +++ b/prolog-xsd2json/cli @@ -0,0 +1,15 @@ +#!/usr/bin/swipl -f -q + +:- encoding(utf8). +:- use_module(xsd2json). +:- use_module(library(http/json)). + + +:- initialization main. + +main :- + current_prolog_flag(argv, Argv), + Argv = [Filename|_], + xsd2json(Filename,JSON), + json_write(user_output,JSON), + halt(0). diff --git a/prolog-xsd2json/cli.pl b/prolog-xsd2json/cli.pl deleted file mode 100644 index 15f0ece..0000000 --- a/prolog-xsd2json/cli.pl +++ /dev/null @@ -1,11 +0,0 @@ -:- encoding(utf8). -:- use_module(xsd2json). -:- use_module(library(http/json)). - -:- initialization main. - -from_stream :- - xsd2json(stream(user_input),JSON), - json_write(user_output,JSON). - -main :- from_stream. diff --git a/prolog-xsd2json/helpers.pl b/prolog-xsd2json/helpers.pl new file mode 100644 index 0000000..95a30e6 --- /dev/null +++ b/prolog-xsd2json/helpers.pl @@ -0,0 +1,18 @@ +:- module(helpers, [ string_concat/2 ]). + + +/** + * string_concat/2 + * string_concat(List_Of_Strings,Concatenated_String) + * + * Concatenates all strings of a given `List_Of_Strings` to + * `Concatenated_String` by use of the predefined + * `string_concat/3`. + * + * Examples: + * string_concat(['a','b','c'], "abc"). + * string_concat([a,b,c],"abc"). + */ +string_concat([],''). +string_concat([A],A). +string_concat([A,B|Bs],Result) :- string_concat(A,B,Temp), string_concat([Temp|Bs],Result). diff --git a/prolog-xsd2json/merge_json.pl b/prolog-xsd2json/merge_json.pl index c736e6b..0b36f25 100644 --- a/prolog-xsd2json/merge_json.pl +++ b/prolog-xsd2json/merge_json.pl @@ -1,5 +1,7 @@ :- encoding(utf8). -:- module(merge_json, [ merge_json/3, merge_json/4, lookup/4 ]). +:- module(merge_json, [ merge_json/3, merge_json/4, merge_facets/3, merge_facet/4, lookup/4 ]). +:- use_module(helpers). + /** * merge_json/4 @@ -24,26 +26,40 @@ merge_json(json([]),json(JSON_List2),json(JSON_List2),_On_Conflict). merge_json(json([Key=Value|Rest_JSON_List1]),json(JSON_List2),json(Merged),On_Conflict) :- - % Key also exists in JSON_List2 and value is equal - lookup(Key,JSON_List2,Value,JSON2_Without_Key), + % Key also exists in JSON_List2 + lookup(Key,JSON_List2,Value2,JSON2_Without_Key), + ( + Value == Value2, + New_Value = Value + ; + % If `Key` is `description` simply concat the values + % by using a \n separator. + Key == description, + string_concat(Value,'\n',ValueNl), + string_concat(ValueNl,Value2,New_Value) + ), merge_json(json(Rest_JSON_List1),json(JSON2_Without_Key),json(Rest_Merged),On_Conflict), - Merged = [Key=Value|Rest_Merged]. + Merged = [Key=New_Value|Rest_Merged]. merge_json(json([Key=Value|Rest_JSON_List1]),json(JSON_List2),json(Merged),On_Conflict) :- % Key also exists in JSON_List2 and value is no atom lookup(Key,JSON_List2,Value_in_JSON_List2,JSON2_Without_Key), \+atom(Value), - % If `Key` is `required` or `enum` use union instead of - % the merge_json/3 predicate which would result - % in an append of both lists. - % This might be necessary due to different orders to - % apply the CHR rules. ( + % If `Key` is `required` or `enum` use union instead of + % the merge_json/3 predicate which would result + % in an append of both lists. + % This might be necessary due to different orders to + % apply the CHR rules. (Key == required; Key == enum), union(Value,Value_in_JSON_List2,Merged_Value) + ; + Key == facets, + merge_facets(Value,Value_in_JSON_List2,Merged_Value) ; Key \== required, Key \== enum, + Key \== facets, merge_json(Value,Value_in_JSON_List2,Merged_Value) ), % merge the rest of the lists independently of the @@ -86,6 +102,37 @@ merge_json(JSON1,JSON2,JSON,hard). +/** + * merge_facets/3. + */ +merge_facets(json([]),json(JSON_List2),json(JSON_List2)). +merge_facets(json(JSON_List1),json([]),json(JSON_List1)) :- JSON_List1 \= []. +merge_facets(json([Key=Value|Rest_JSON_List1]),json(JSON_List2),json(JSON)) :- + lookup(Key,JSON_List2,Value_in_JSON_List2,JSON2_Without_Key), + merge_facet(Key,Value,Value_in_JSON_List2,Merged_Value), + merge_facets(json(Rest_JSON_List1),json(JSON2_Without_Key),json(Rest_Merged)), + JSON = [Key=Merged_Value|Rest_Merged]. +merge_facets(json([Key=Value|Rest_JSON_List1]),json(JSON_List2),json(JSON)) :- + \+lookup(Key,JSON_List2,_Value_in_JSON_List2), + merge_facets(json(Rest_JSON_List1),json(JSON_List2),json(Rest_Merged)), + JSON = [Key=Value|Rest_Merged]. + + +/** + * merge_facet/4 + * merge_facet(Facet,Value1,Value2,Result_Value) + */ +merge_facet(minLength,A,B,A) :- A >= B. +merge_facet(minLength,A,B,B) :- A < B. +merge_facet(maxLength,A,B,A) :- A =< B. +merge_facet(maxLength,A,B,B) :- A > B. +merge_facet(minimum,A,B,A) :- A >= B. +merge_facet(minimum,A,B,B) :- A < B. +merge_facet(maximum,A,B,A) :- A =< B. +merge_facet(maximum,A,B,B) :- A > B. +merge_facet(pattern,A,B,R) :- string_concat(['(',A,'|',B,')'],R). + + /** * lookup/3 * lookup(Key,Key_Value_List,Value) @@ -115,4 +162,4 @@ lookup(Key,[Key=Value|Without_Key],Value,Without_Key). lookup(Key,[Not_Key=Some_Value|Rest],Value,[Not_Key=Some_Value|Without_Key]) :- Key \= Not_Key, - lookup(Key,Rest,Value,Without_Key). \ No newline at end of file + lookup(Key,Rest,Value,Without_Key). diff --git a/prolog-xsd2json/xsd2json.pl b/prolog-xsd2json/xsd2json.pl index 68693de..4ab5561 100644 --- a/prolog-xsd2json/xsd2json.pl +++ b/prolog-xsd2json/xsd2json.pl @@ -1,117 +1,123 @@ :- module(xsd2json, [ xsd2json/2, flatten_xsd/1 ]). :- use_module(merge_json). +:- use_module(helpers). :- use_module(library(chr)). +:- use_module(library(http/http_open)). +:- use_module(library(url)). /** - * transform/0 + * transform/1 * [CHR-Constraint] * * Constraint to trigger the transformation process. */ -:- chr_constraint transform/0. +:- chr_constraint transform/1. /** - * build_schema/0 + * build_schema/1 * [CHR-Constraint] * * Constraint to trigger the build process of the global * JSON Schema, i.e. create inline JSON Schemas. */ -:- chr_constraint build_schema/0. -build_schema +:- chr_constraint build_schema/1. +build_schema(IName) \ - transform + transform(IName) <=> true. /** - * json/2 - * json(ID,json(JSON)) + * json/3 + * json(IName,ID,json(JSON)) * [CHR-Constraint] * - * The `json/2` constraints holds the `JSON` entity for the + * The `json/3` constraints holds the `JSON` entity for the * XSD object with the same `ID`. */ -:- chr_constraint json/2. +:- chr_constraint json/3. /** * Merge two JSONs of the same `ID`. */ -json(ID,JSON1), - json(ID,JSON2) +json(IName,ID,JSON1), + json(IName,ID,JSON2) <=> merge_json(JSON1,JSON2,JSON) | - json(ID,JSON). + json(IName,ID,JSON). /** - * json_created/2 - * json_created(ID,List_Of_Children_IDs) + * json_created/3 + * json_created(IName,ID,List_Of_Children_IDs) * [CHR-Constraint] * - * The `json_created/2` holds a `List_Of_Children_IDs` + * The `json_created/3` holds a `List_Of_Children_IDs` * of children nodes of the given `ID` for which * already `json/2` constraints has been generated. */ -:- chr_constraint json_created/2. +:- chr_constraint json_created/3. /** - * Merge two `json_created/2` constraints of the same ID. + * Merge two `json_created/3` constraints of the same ID. */ -json_created(ID,List1), - json_created(ID,List2) +json_created(IName,ID,List1), + json_created(IName,ID,List2) <=> union(List1,List2,Union), - json_created(ID,Union). + json_created(IName,ID,Union). + + +:- chr_constraint xsd2json_result/2. /** - * Propagate for each created JSON a `json_created/2` + * Propagate for each created JSON a `json_created` * constraint for the parent node. */ -json(ID,_JSON), - node(_Namespace,_Name,ID,_Siblings,Parent_ID) +json(IName,ID,_JSON), + node(IName,_Namespace,_Name,ID,_Siblings,Parent_ID) ==> - json_created(Parent_ID,[ID]). + json_created(IName,Parent_ID,[ID]). /** - * schema_definition/3 - * schema_definition(Schema_Name,ID,JSON) + * schema_definition/4 + * schema_definition(IName,Schema_Name,ID,JSON) * [CHR-Constraint] * * Definition of a inline JSON Schema, assigned to * the node of `ID`. */ -:- chr_constraint schema_definition/3. +:- chr_constraint schema_definition/4. -schema_definition(Name,ID,JSON1), - schema_definition(Name,ID,JSON2) +schema_definition(IName,Name,ID,JSON1), + schema_definition(IName,Name,ID,JSON2) <=> merge_json(JSON1,JSON2,JSON) | - schema_definition(Name,ID,JSON). + schema_definition(IName,Name,ID,JSON). /** - * node/5 - * node(Namespace,Name,ID,Children_IDs,Parent_ID) + * node/6 + * node(IName,Namespace,Name,ID,Children_IDs,Parent_ID) * [CHR-Constraint] * * Hold the node's information like its `Name`, `Namespace`, * `ID` and children as well as the `Parent_ID` of its * parent node. */ -:- chr_constraint node/5. +:- chr_constraint node/6. /** - * node_attribute/4 - * node_attribute(ID,Key,Value,Source) + * node_attribute/5 + * node_attribute(IName,ID,Key,Value,Source) * [CHR-Constraint] * * Hold the attribute of the node of `ID`as a @@ -121,28 +127,28 @@ * Note: The `Value` is always a string. * * Examples: - * node_attribute(_Some_ID,minOccurs,'1',default). + * node_attribute('file.xsd',_Some_ID,minOccurs,'1',default). */ -:- chr_constraint node_attribute/4. +:- chr_constraint node_attribute/5. % remove default attributes if the source already contains % it -node_attribute(ID,Key,_Value_Kept,source) +node_attribute(IName,ID,Key,_Value_Kept,source) \ - node_attribute(ID,Key,_Value_Removed,default) + node_attribute(IName,ID,Key,_Value_Removed,default) <=> true. /** - * text_node/3 - * text_node(ID,Text,Parent_ID) + * text_node/4 + * text_node(Input_Name,ID,Text,Parent_ID) * [CHR-Constraint] * * Representation of a XML text node like it is used * in `My Documentation` */ -:- chr_constraint text_node/3. +:- chr_constraint text_node/4. /** @@ -192,8 +198,18 @@ * load_xsd(stream(user_input),XSD). %% binds XSD to the DOM tree */ load_xsd(Input,XSD) :- - parse_options(Parse_Options), - load_structure(Input,XSD,Parse_Options). + parse_options(Parse_Options), + ( + ( + string_concat('http://',_,Input) + ; + string_concat('https://',_,Input) + ), + http_open:http_open(Input,In,[]) + ; + In = Input + ), + load_structure(In,XSD,Parse_Options). /** @@ -210,7 +226,8 @@ flatten_xsd(Input) :- load_xsd(Input,XSD), root_id(Root_ID), - xsd_flatten_nodes(Root_ID,0,XSD,_Children_IDs). + input_name(Input,Input_Name), + xsd_flatten_nodes(Input_Name,Root_ID,0,XSD,_Children_IDs). /** @@ -224,12 +241,27 @@ xsd2json(Input,Result) :- load_xsd(Input,XSD), root_id(Root_ID), - xsd_flatten_nodes(Root_ID,0,XSD,Children_IDs), - transform, + input_name(Input,Input_Name), + xsd_flatten_nodes(Input_Name,Root_ID,0,XSD,Children_IDs), + transform(Input_Name), Children_IDs = [First_Element|_], - build_schema, - get_json(First_Element,JSON), - remove_at_from_property_names(JSON,Result). + build_schema(Input_Name), + get_json(Input_Name,First_Element,JSON), + cleanup_json(JSON,Result), + xsd2json_result(Input_Name,Result). + + +/** + * input_name/2. + * + * Create an Input_Name for a given input resource. + */ +input_name(stream(A),R) :- + string_concat('stream_',A,R). +input_name(Input,Input) :- + is_absolute_url(Input). +input_name(Filepath,Abs_Filepath) :- + absolute_file_name(Filepath,Abs_Filepath). /** @@ -367,20 +399,15 @@ /** - * string_concat/2 - * string_concat(List_Of_Strings,Concatenated_String) - * - * Concatenates all strings of a given `List_Of_Strings` to - * `Concatenated_String` by use of the predefined - * `string_concat/3`. + * relative_input/3 * * Examples: - * string_concat(['a','b','c'], "abc"). - * string_concat([a,b,c],"abc"). + * relative_input('../test/a.xsd','b.xsd','../test/b.xsd'). + * relative_input('http://localhost/a.xsd','b.xsd','http://localhost/b.xsd'). */ -string_concat([],''). -string_concat([A],A). -string_concat([A,B|Bs],Result) :- string_concat(A,B,Temp), string_concat([Temp|Bs],Result). +relative_input(Base,Relative,Res) :- + file_directory_name(Base,Dir), + directory_file_path(Dir,Relative,Res). /** @@ -413,6 +440,14 @@ elength(Ls,Length). +/** + * cleanup_json/2 + */ +cleanup_json(JSON,Result) :- + remove_at_from_property_names(JSON,R1), + R1 = R2, % TODO: resolve_facets(R1,R2) + Result = R2. + /** * remove_at_from_property_names/2 * remove_at_from_property_names(JSON,New_JSON) @@ -493,10 +528,6 @@ remove_at_from_property_names(json(Value),json(New_Value)), JSON = json([Key=json(New_Value)|New_Rest]). -remove_at_from_property_names(JSON,H) :- - var(H), - write(' (1) Not found at remove_at_from_property_names/2: '), write(JSON), nl, nl. - /** * mark_attribute/1 @@ -541,52 +572,52 @@ /** - * xsd_flatten_nodes/4 + * xsd_flatten_nodes/5 * - * Flatten a XSD DOM tree by creating `node/4`, + * Flatten a XSD DOM tree by creating `node/5`, * `attribute/` - * and `text_node/2` constraints. + * and `text_node/3` constraints. */ -xsd_flatten_nodes(_Base_ID,_Pos,[],[]). +xsd_flatten_nodes(_IName,_Base_ID,_Pos,[],[]). -xsd_flatten_nodes(Base_ID,Pos,[Node|Nodes],[ID|Sibling_IDs]) :- +xsd_flatten_nodes(IName,Base_ID,Pos,[Node|Nodes],[ID|Sibling_IDs]) :- Node = element(Node_Type,Node_Attributes,Child_Nodes), %% is an XML node, no text new_id(Base_ID,Pos,ID), namespace(Node_Type,Namespace,Node_Type_Without_NS), % flatten the node's attributes - xsd_flatten_attributes(ID,Node_Attributes), - node(Namespace,Node_Type_Without_NS,ID,Children_IDs,Base_ID), + xsd_flatten_attributes(IName,ID,Node_Attributes), + node(IName,Namespace,Node_Type_Without_NS,ID,Children_IDs,Base_ID), % flatten sibling nodes Next_Pos is Pos+1, - xsd_flatten_nodes(Base_ID,Next_Pos,Nodes,Sibling_IDs), + xsd_flatten_nodes(IName,Base_ID,Next_Pos,Nodes,Sibling_IDs), % flatten all children - xsd_flatten_nodes(ID,0,Child_Nodes,Children_IDs). + xsd_flatten_nodes(IName,ID,0,Child_Nodes,Children_IDs). -xsd_flatten_nodes(Base_ID,Pos,[Node|Nodes],[ID|Sibling_IDs]) :- +xsd_flatten_nodes(IName,Base_ID,Pos,[Node|Nodes],[ID|Sibling_IDs]) :- atom(Node), %% is simply a text node new_id(Base_ID,Pos,ID), - text_node(ID,Node,Base_ID), + text_node(IName,ID,Node,Base_ID), % flatten sibling nodes Next_Pos is Pos+1, - xsd_flatten_nodes(Base_ID,Next_Pos,Nodes,Sibling_IDs). + xsd_flatten_nodes(IName,Base_ID,Next_Pos,Nodes,Sibling_IDs). /** - * xsd_flatten_attributes/2 - * xsd_flatten_attributes(ID,List_Of_Attributes) + * xsd_flatten_attributes/3 + * xsd_flatten_attributes(IName,ID,List_Of_Attributes) * * Flatten a `List_Of_Attributes` of the form - * [attribute1=valu1,attribute2=value2,...] - * by creating a `node_attribute/3` constraints. + * [attribute1=value1,attribute2=value2,...] + * by creating `node_attribute/4` constraints. * * Examples: - * xsd_flatten_attributes([0],[minOccurs='1']) - * ==> node_attribute([0],minOccurs,'1') + * xsd_flatten_attributes('file.xsd',[0],[minOccurs='1']) + * ==> node_attribute('file.xsd',[0],minOccurs,'1') */ -xsd_flatten_attributes(_ID,[]). -xsd_flatten_attributes(ID,[Attribute=Value|List_Of_Attributes]) :- - node_attribute(ID,Attribute,Value,source), - xsd_flatten_attributes(ID,List_Of_Attributes). +xsd_flatten_attributes(_IName,_ID,[]). +xsd_flatten_attributes(IName,ID,[Attribute=Value|List_Of_Attributes]) :- + node_attribute(IName,ID,Attribute,Value,source), + xsd_flatten_attributes(IName,ID,List_Of_Attributes). /** @@ -647,8 +678,8 @@ convert_xsd_type(positiveInteger,json([type=integer,minimum=0,exclusiveMinimum= @(true)])). convert_xsd_type(negativeInteger,json([type=integer,maximum=0,exclusiveMaximum= @(true)])). -convert_xsd_type(nonPositiveInteger,json([type=integer,maximum=0,exclusiveMaximum= @(false)])). -convert_xsd_type(nonNegativeInteger,json([type=integer,minimum=0,exclusiveMinimum= @(false)])). +convert_xsd_type(nonPositiveInteger,json([type=integer,maximum=0,exclusiveMaximum= @false])). +convert_xsd_type(nonNegativeInteger,json([type=integer,minimum=0,exclusiveMinimum= @false])). /** @@ -673,12 +704,12 @@ % minInclusive convert_xsd_restriction(minInclusive,Value,json(JSON_List)) :- to_number(Value,Number), - JSON_List = [minimum=Number,exclusiveMinimum= @(false)]. + JSON_List = [minimum=Number,exclusiveMinimum= @false]. % maxInclusive convert_xsd_restriction(maxInclusive,Value,json(JSON_List)) :- to_number(Value,Number), - JSON_List = [maximum=Number,exclusiveMaximum= @(false)]. + JSON_List = [maximum=Number,exclusiveMaximum= @false]. % minLength convert_xsd_restriction(minLength,Value,json(JSON_List)) :- @@ -757,7 +788,7 @@ * remove_xsd_element/1 * remove_xsd_element(Element_Name) */ -node(Namespace,Name,_ID,_Children,_Parent_ID) +node(_IName,Namespace,Name,_ID,_Children,_Parent_ID) <=> remove_xsd_element(Name), xsd_namespace(Namespace) @@ -766,31 +797,31 @@ /** - * remove_node/1 - * remove_node(ID) + * remove_node/2 + * remove_node(IName,ID) * [CHR-Constraint] * - * Remove a `node/4` constraint and its `node_attribute/4` + * Remove a `node` constraint and its `node_attribute` * constraints as well as its children nodes. */ -:- chr_constraint remove_node/1. -remove_node(ID) +:- chr_constraint remove_node/2. +remove_node(IName,ID) \ - node_attribute(ID,_,_,_) + node_attribute(IName,ID,_,_,_) <=> true. -remove_node(ID) +remove_node(IName,ID) \ - node(Parent_Namespace,Parent_Name,Parent_ID,Siblings,Parent_Parent_ID) + node(IName,Parent_Namespace,Parent_Name,Parent_ID,Siblings,Parent_Parent_ID) <=> member(ID,Siblings), delete(Siblings,ID,Siblings_Without_ID) | - node(Parent_Namespace,Parent_Name,Parent_ID,Siblings_Without_ID,Parent_Parent_ID). + node(IName,Parent_Namespace,Parent_Name,Parent_ID,Siblings_Without_ID,Parent_Parent_ID). -remove_node(ID) \ json(ID,_) <=> true. -remove_node(ID) \ node(_,_,ID,Children,_) <=> remove_nodes(Children). +remove_node(IName,ID) \ json(IName,ID,_) <=> true. +remove_node(IName,ID) \ node(IName,_,_,ID,Children,_) <=> remove_nodes(IName,Children). /** @@ -800,17 +831,17 @@ * Remove a list of `node/4` constraints by use of * the `remove_node/1` constraint. */ -remove_nodes([]). -remove_nodes([ID|Rest]) :- - remove_node(ID), - remove_nodes(Rest). +remove_nodes(_IName,[]). +remove_nodes(IName,[ID|Rest]) :- + remove_node(IName,ID), + remove_nodes(IName,Rest). /** - * ##### DO BEFORE transform/0 ##### + * ##### DO BEFORE transform/1 ##### * * Manipulations which has to be done before - * the conversion starts, i.e. before the `transform/0` + * the conversion starts, i.e. before the `transform/1` * constrains was added. */ @@ -818,27 +849,27 @@ * Combine multiple `xs:element` within a `xs:sequence` * with the same `Name` and `Type`. */ -node(NS1,sequence,Sequence_ID,_Sequence_Children,_Sequence_Parent_ID), - node_attribute(Element_1_ID,name,Name,_), - node_attribute(Element_1_ID,type,Type,_) +node(IName,NS1,sequence,Sequence_ID,_Sequence_Children,_Sequence_Parent_ID), + node_attribute(IName,Element_1_ID,name,Name,_), + node_attribute(IName,Element_1_ID,type,Type,_) \ - node(NS2,element,Element_1_ID,Element_1_Children,Sequence_ID), - node(NS3,element,Element_2_ID,_Element_2_Children,Sequence_ID), - node_attribute(Element_2_ID,name,Name,_), - node_attribute(Element_2_ID,type,Type,_), - node_attribute(Element_1_ID,minOccurs,MinOccurs_1,_), - node_attribute(Element_1_ID,maxOccurs,MaxOccurs_1,_), - node_attribute(Element_2_ID,minOccurs,MinOccurs_2,_), - node_attribute(Element_2_ID,maxOccurs,MaxOccurs_2,_) + node(IName,NS2,element,Element_1_ID,Element_1_Children,Sequence_ID), + node(IName,NS3,element,Element_2_ID,_Element_2_Children,Sequence_ID), + node_attribute(IName,Element_2_ID,name,Name,_), + node_attribute(IName,Element_2_ID,type,Type,_), + node_attribute(IName,Element_1_ID,minOccurs,MinOccurs_1,_), + node_attribute(IName,Element_1_ID,maxOccurs,MaxOccurs_1,_), + node_attribute(IName,Element_2_ID,minOccurs,MinOccurs_2,_), + node_attribute(IName,Element_2_ID,maxOccurs,MaxOccurs_2,_) <=> xsd_namespaces([NS1,NS2,NS3]), sum_occurs(MinOccurs_1,MinOccurs_2,MinOccurs), sum_occurs(MaxOccurs_1,MaxOccurs_2,MaxOccurs) | - remove_node(Element_2_ID), - node(NS1,element,Element_1_ID,Element_1_Children,Sequence_ID), - node_attribute(Element_1_ID,minOccurs,MinOccurs,source), - node_attribute(Element_1_ID,maxOccurs,MaxOccurs,source). + remove_node(IName,Element_2_ID), + node(IName,NS1,element,Element_1_ID,Element_1_Children,Sequence_ID), + node_attribute(IName,Element_1_ID,minOccurs,MinOccurs,source), + node_attribute(IName,Element_1_ID,maxOccurs,MaxOccurs,source). /** @@ -848,39 +879,26 @@ * http://www.w3.org/TR/xmlschema-2/#src-multiple-patterns * they are ORed. */ -node(NS1,restriction,Restriction_ID,_Restriction_Children,_Restriction_Parent_ID) +node(IName,NS1,restriction,Restriction_ID,_Restriction_Children,_Restriction_Parent_ID) \ - node(NS2,pattern,Pattern_1_ID,Pattern_1_Children,Restriction_ID), - node(NS3,pattern,Pattern_2_ID,_Pattern_2_Children,Restriction_ID), - node_attribute(Pattern_1_ID,value,Pattern_1,_), - node_attribute(Pattern_2_ID,value,Pattern_2,_) + node(IName,NS2,pattern,Pattern_1_ID,Pattern_1_Children,Restriction_ID), + node(IName,NS3,pattern,Pattern_2_ID,_Pattern_2_Children,Restriction_ID), + node_attribute(IName,Pattern_1_ID,value,Pattern_1,_), + node_attribute(IName,Pattern_2_ID,value,Pattern_2,_) <=> xsd_namespaces([NS1,NS2,NS3]), string_concat(['(',Pattern_1,'|',Pattern_2,')'],New_Pattern) | - remove_node(Pattern_2_ID), - node(NS2,pattern,Pattern_1_ID,Pattern_1_Children,Restriction_ID), - node_attribute(Pattern_1_ID,value,New_Pattern,source). - - -/** - * - */ -%% node(NS1,complexType,ComplexType_ID,_ComplexType_Children,_ComplexType_Parent_ID), -%% json(ComplexType_ID,json(JSON)) -%% \ -%% node(NS2,attribute,Attribute_ID,_Attribute_Children,ComplexType_ID) -%% <=> -%% xsd_namespaces([NS1,NS2,NS3]) -%% merge_json:lookup(properties,) - + remove_node(IName,Pattern_2_ID), + node(IName,NS2,pattern,Pattern_1_ID,Pattern_1_Children,Restriction_ID), + node_attribute(IName,Pattern_1_ID,value,New_Pattern,source). /** * ## Set defaults ## * * Note: This will already be executed without the - * `transform/0` constraint being added. + * `transform/1` constraint being added. */ /** @@ -893,50 +911,50 @@ * This can be ignored as it will have no effect for * those elements. */ -node(Namespace,element,Element_ID,_Element_Children,_Parent_ID) +node(IName,Namespace,element,Element_ID,_Element_Children,_Parent_ID) ==> xsd_namespace(Namespace) | - node_attribute(Element_ID,minOccurs,'1',default). + node_attribute(IName,Element_ID,minOccurs,'1',default). -node(Namespace,element,Element_ID,_Element_Children,_Parent_ID) +node(IName,Namespace,element,Element_ID,_Element_Children,_Parent_ID) ==> xsd_namespace(Namespace) | - node_attribute(Element_ID,maxOccurs,'1',default). + node_attribute(IName,Element_ID,maxOccurs,'1',default). /** * Add `use` attribute to all `xs:attribute` XSD nodes. * Default is `optional`. */ -node(Namespace,attribute,Attribute_ID,_Attribute_Children,_Parent_ID) +node(IName,Namespace,attribute,Attribute_ID,_Attribute_Children,_Parent_ID) ==> xsd_namespace(Namespace) | - node_attribute(Attribute_ID,use,optional,default). + node_attribute(IName,Attribute_ID,use,optional,default). /** * Add `fixed` attribute to all `xs:attribute` XSD nodes. * Default is not set, i.e. `var(Fixed)`. */ -node(Namespace,attribute,Attribute_ID,_Attribute_Children,_Parent_ID) +node(IName,Namespace,attribute,Attribute_ID,_Attribute_Children,_Parent_ID) ==> xsd_namespace(Namespace) | - node_attribute(Attribute_ID,fixed,_Unbound,default). + node_attribute(IName,Attribute_ID,fixed,_Unbound,default). /** * Add `default` attribute to all `xs:attribute` XSD nodes. * Default is not set, i.e. `var(Default)`. */ -node(Namespace,attribute,Attribute_ID,_Attribute_Children,_Parent_ID) +node(IName,Namespace,attribute,Attribute_ID,_Attribute_Children,_Parent_ID) ==> xsd_namespace(Namespace) | - node_attribute(Attribute_ID,default,_Unbound,default). + node_attribute(IName,Attribute_ID,default,_Unbound,default). /** @@ -946,22 +964,22 @@ * This `id` isn't used yet as there is no equivalent in * JSON Schema. */ -node(Namespace,attribute,Attribute_ID,_Attribute_Children,_Parent_ID) +node(IName,Namespace,attribute,Attribute_ID,_Attribute_Children,_Parent_ID) ==> xsd_namespace(Namespace) | - node_attribute(Attribute_ID,id,_Unbound,default). + node_attribute(IName,Attribute_ID,id,_Unbound,default). /** * Add `type` attribute to all `xs:attribute` XSD nodes. * Default is not set, i.e. `var(Type)`. */ -node(Namespace,attribute,Attribute_ID,_Attribute_Children,_Parent_ID) +node(IName,Namespace,attribute,Attribute_ID,_Attribute_Children,_Parent_ID) ==> xsd_namespace(Namespace) | - node_attribute(Attribute_ID,type,_Unbound,default). + node_attribute(IName,Attribute_ID,type,_Unbound,default). /** @@ -972,16 +990,16 @@ * Every restriction has at least its base type in an `base=Base` * attribute. */ -transform, - node(Namespace,restriction,ID,_Children,_Parent_ID), - node_attribute(ID,base,Base,_) +transform(IName), + node(IName,Namespace,restriction,ID,_Children,_Parent_ID), + node_attribute(IName,ID,base,Base,_) ==> xsd_namespace(Namespace), namespace(Base,Base_Namespace,Base_Type), xsd_namespace(Base_Namespace), convert_xsd_type(Base_Type,JSON) | - json(ID,JSON). + json(IName,ID,JSON). /** @@ -991,14 +1009,14 @@ /** * `xs:enumeration` element as child of a `xs:restriction` node. */ -transform, - node(NS1,restriction,Restriction_ID,_Restriction_Children,_Restriction_Parent_ID), - node(NS2,enumeration,Enumeration_ID,_Enumeration_Children,Restriction_ID), - node_attribute(Enumeration_ID,value,Value,_) +transform(IName), + node(IName,NS1,restriction,Restriction_ID,_Restriction_Children,_Restriction_Parent_ID), + node(IName,NS2,enumeration,Enumeration_ID,_Enumeration_Children,Restriction_ID), + node_attribute(IName,Enumeration_ID,value,Value,_) ==> xsd_namespaces([NS1,NS2]) | - json(Restriction_ID,json([enum=[Value]])). + json(IName,Restriction_ID,json([enum=[Value]])). /** @@ -1017,15 +1035,15 @@ * while the specification also mentions date and time * facets. */ -transform, - node(NS1,restriction,Restriction_ID,_Restriction_Children,_Restriction_Parent_ID), - node(NS2,Constraint_Name_XSD,Constraint_ID,_Constraint_Children,Restriction_ID), - node_attribute(Constraint_ID,value,Value,_) +transform(IName), + node(IName,NS1,restriction,Restriction_ID,_Restriction_Children,_Restriction_Parent_ID), + node(IName,NS2,Facet_Name_XSD,Facet_ID,_Facet_Children,Restriction_ID), + node_attribute(IName,Facet_ID,value,Value,_) ==> xsd_namespaces([NS1,NS2]), - convert_xsd_restriction(Constraint_Name_XSD,Value,json(JSON_List)) + convert_xsd_restriction(Facet_Name_XSD,Value,json(JSON_List)) | - json(Restriction_ID,json(JSON_List)). + json(IName,Restriction_ID,json(JSON_List)). /** @@ -1035,42 +1053,42 @@ /** * `xs:element` with `fixed` attribute set. */ -transform, - node(Namespace,element,ID,_Children,_Element_Parent_ID), - node_attribute(ID,fixed,Fixed,_) +transform(IName), + node(IName,Namespace,element,ID,_Children,_Element_Parent_ID), + node_attribute(IName,ID,fixed,Fixed,_) ==> xsd_namespace(Namespace) | - json(ID,json([enum=[Fixed]])). + json(IName,ID,json([enum=[Fixed]])). /** * `xs:element` with `type` attribute set which can be * translated to a primitive JSON Schema type. */ -transform, - node(Namespace,element,ID,_Children,_Element_Parent_ID), - node_attribute(ID,type,Type_With_NS,_) +transform(IName), + node(IName,Namespace,element,ID,_Children,_Element_Parent_ID), + node_attribute(IName,ID,type,Type_With_NS,_) ==> xsd_namespace(Namespace), valid_xsd_type(Type_With_NS,Type) | convert_xsd_type(Type,JSON), - json(ID,JSON). + json(IName,ID,JSON). /** * `xs:element` with `type` attribute set which must be * self defined. */ -transform, - node(Namespace,element,ID,_Children,_Element_Parent_ID), - node_attribute(ID,type,Type_With_NS,_) +transform(IName), + node(IName,Namespace,element,ID,_Children,_Element_Parent_ID), + node_attribute(IName,ID,type,Type_With_NS,_) ==> xsd_namespace(Namespace), \+valid_xsd_type(Type_With_NS,_Type) | - json(ID,json([type=Type_With_NS])). + json(IName,ID,json([type=Type_With_NS])). /** @@ -1082,31 +1100,31 @@ * Convert a `xs:annotation/xs:documentation` within a * `xs:element` node. */ -transform, - node(NS1,element,Element_ID,_Element_Children,_Element_Parent_ID), - node(NS2,annotation,Annotation_ID,_Annotation_Children,Element_ID), - node(NS3,documentation,Documentation_ID,_Documentation_Children,Annotation_ID), - text_node(_Text_Node_ID,Text,Documentation_ID) +transform(IName), + node(IName,NS1,element,Element_ID,_Element_Children,_Element_Parent_ID), + node(IName,NS2,annotation,Annotation_ID,_Annotation_Children,Element_ID), + node(IName,NS3,documentation,Documentation_ID,_Documentation_Children,Annotation_ID), + text_node(IName,_Text_Node_ID,Text,Documentation_ID) ==> xsd_namespaces([NS1,NS2,NS3]) | - json(Element_ID,json([description=Text])). + json(IName,Element_ID,json([description=Text])). /** * Convert a `xs:annotation/xs:documentation` within a * `xs:simpleType` node which has a `@name` attribute set. */ -transform, - node(NS1,simpleType,SimpleType_ID,_SimpleType_Children,_SimpleType_Parent_ID), - node_attribute(SimpleType_ID,name,_Name,_), - node(NS2,annotation,Annotation_ID,_Annotation_Children,SimpleType_ID), - node(NS3,documentation,Documentation_ID,_Documentation_Children,Annotation_ID), - text_node(_Text_Node_ID,Text,Documentation_ID) +transform(IName), + node(IName,NS1,simpleType,SimpleType_ID,_SimpleType_Children,_SimpleType_Parent_ID), + node_attribute(IName,SimpleType_ID,name,_Name,_), + node(IName,NS2,annotation,Annotation_ID,_Annotation_Children,SimpleType_ID), + node(IName,NS3,documentation,Documentation_ID,_Documentation_Children,Annotation_ID), + text_node(IName,_Text_Node_ID,Text,Documentation_ID) ==> xsd_namespaces([NS1,NS2,NS3]) | - json(SimpleType_ID,json([description=Text])). + json(IName,SimpleType_ID,json([description=Text])). /** @@ -1155,13 +1173,13 @@ * definition) and `MaxOccurs` (1) values by use of the * `is_required_property/2` predicate. */ -transform, - node(NS1,all,All_ID,_All_Children,_All_Parent_ID), - node(NS2,element,Element_ID,_Element_Children,All_ID), - json(Element_ID,Element_JSON), - node_attribute(Element_ID,minOccurs,MinOccurs,_), - node_attribute(Element_ID,maxOccurs,MaxOccurs,_), - node_attribute(Element_ID,name,Element_Name,_) +transform(IName), + node(IName,NS1,all,All_ID,_All_Children,_All_Parent_ID), + node(IName,NS2,element,Element_ID,_Element_Children,All_ID), + json(IName,Element_ID,Element_JSON), + node_attribute(IName,Element_ID,minOccurs,MinOccurs,_), + node_attribute(IName,Element_ID,maxOccurs,MaxOccurs,_), + node_attribute(IName,Element_ID,name,Element_Name,_) ==> xsd_namespaces([NS1,NS2]) | @@ -1174,7 +1192,7 @@ \+is_required_property(MinOccurs,MaxOccurs), Full_JSON = JSON ), - json(All_ID,json(Full_JSON)). + json(IName,All_ID,json(Full_JSON)). /** @@ -1185,13 +1203,13 @@ * `xs:element` within a `xs:sequence` with the `maxOccurs` attribute * set to '1' and `minOccurs` to '0' or '1'. */ -transform, - node(NS1,sequence,Sequence_ID,_Sequence_Children,_Sequence_Parent_ID), - node(NS2,element,Element_ID,_Element_Children,Sequence_ID), - json(Element_ID,Element_JSON), - node_attribute(Element_ID,minOccurs,MinOccurs,_), - node_attribute(Element_ID,maxOccurs,'1',_), - node_attribute(Element_ID,name,Element_Name,_) +transform(IName), + node(IName,NS1,sequence,Sequence_ID,_Sequence_Children,_Sequence_Parent_ID), + node(IName,NS2,element,Element_ID,_Element_Children,Sequence_ID), + json(IName,Element_ID,Element_JSON), + node_attribute(IName,Element_ID,minOccurs,MinOccurs,_), + node_attribute(IName,Element_ID,maxOccurs,'1',_), + node_attribute(IName,Element_ID,name,Element_Name,_) ==> xsd_namespaces([NS1,NS2]) | @@ -1200,20 +1218,20 @@ % add `required=[...]` if `minOccurs` = 1 (MinOccurs = '0', Full_JSON = JSON; MinOccurs = '1', Full_JSON = [required=[Element_Name]|JSON]), - json(Sequence_ID,json(Full_JSON)). + json(IName,Sequence_ID,json(Full_JSON)). /** * `xs:element` within a `xs:sequence` with the `maxOccurs` attribute * set to 'unbounded' or >= 2. */ -transform, - node(NS1,sequence,Sequence_ID,_Sequence_Children,_Sequence_Parent_ID), - node(NS2,element,Element_ID,_Element_Children,Sequence_ID), - json(Element_ID,Element_JSON), - node_attribute(Element_ID,minOccurs,MinOccurs,_), - node_attribute(Element_ID,maxOccurs,MaxOccurs,_), - node_attribute(Element_ID,name,Element_Name,_) +transform(IName), + node(IName,NS1,sequence,Sequence_ID,_Sequence_Children,_Sequence_Parent_ID), + node(IName,NS2,element,Element_ID,_Element_Children,Sequence_ID), + json(IName,Element_ID,Element_JSON), + node_attribute(IName,Element_ID,minOccurs,MinOccurs,_), + node_attribute(IName,Element_ID,maxOccurs,MaxOccurs,_), + node_attribute(IName,Element_ID,name,Element_Name,_) ==> xsd_namespaces([NS1,NS2]), to_number(MinOccurs,MinOccurs_Number), @@ -1244,7 +1262,7 @@ % add `required=[...]` if `minOccurs` > 0 (MinOccurs_Number >= 1, Full_JSON = [required=[Element_Name]|JSON]; MinOccurs_Number < 1, Full_JSON = JSON), - json(Sequence_ID,json(Full_JSON)). + json(IName,Sequence_ID,json(Full_JSON)). /** @@ -1254,27 +1272,27 @@ /** * `xs:complexType` which has a `xs:all` child. */ -transform, - node(NS1,complexType,ComplexType_ID,_ComplexType_Children,_ComplexType_Parent_ID), - node(NS2,all,All_ID,_All_Children,ComplexType_ID), - json(All_ID,All_JSON) +transform(IName), + node(IName,NS1,complexType,ComplexType_ID,_ComplexType_Children,_ComplexType_Parent_ID), + node(IName,NS2,all,All_ID,_All_Children,ComplexType_ID), + json(IName,All_ID,All_JSON) ==> xsd_namespaces([NS1,NS2]) | - json(ComplexType_ID,All_JSON). + json(IName,ComplexType_ID,All_JSON). /** * `xs:complexType` which has a `xs:sequence` child. */ -transform, - node(NS1,complexType,ComplexType_ID,_ComplexType_Children,_ComplexType_Parent_ID), - node(NS2,sequence,Sequence_ID,_Sequence_Children,ComplexType_ID), - json(Sequence_ID,Sequence_JSON) +transform(IName), + node(IName,NS1,complexType,ComplexType_ID,_ComplexType_Children,_ComplexType_Parent_ID), + node(IName,NS2,sequence,Sequence_ID,_Sequence_Children,ComplexType_ID), + json(IName,Sequence_ID,Sequence_JSON) ==> xsd_namespaces([NS1,NS2]) | - json(ComplexType_ID,Sequence_JSON). + json(IName,ComplexType_ID,Sequence_JSON). /** @@ -1290,14 +1308,14 @@ * - form * - id */ -transform, - node(NS1,complexType,ComplexType_ID,_ComplexType_Children,_ComplexType_Parent_ID), - node(NS2,attribute,Attribute_ID,_Attribute_Children,ComplexType_ID), - node_attribute(Attribute_ID,name,Attribute_Name,_), - node_attribute(Attribute_ID,type,Type_With_NS,_), - node_attribute(Attribute_ID,use,Use,_), - node_attribute(Attribute_ID,fixed,Fixed,_), - node_attribute(Attribute_ID,default,Default,_) +transform(IName), + node(IName,NS1,complexType,ComplexType_ID,_ComplexType_Children,_ComplexType_Parent_ID), + node(IName,NS2,attribute,Attribute_ID,_Attribute_Children,ComplexType_ID), + node_attribute(IName,Attribute_ID,name,Attribute_Name,_), + node_attribute(IName,Attribute_ID,type,Type_With_NS,_), + node_attribute(IName,Attribute_ID,use,Use,_), + node_attribute(IName,Attribute_ID,fixed,Fixed,_), + node_attribute(IName,Attribute_ID,default,Default,_) ==> \+var(Type_With_NS), xsd_namespaces([NS1,NS2]), @@ -1343,7 +1361,7 @@ Use \= required, JSON2 = JSON1 ), - json(ComplexType_ID,json(JSON2)). + json(IName,ComplexType_ID,json(JSON2)). /** @@ -1354,16 +1372,16 @@ * This rule will be called once the JSON for the inner * `xs:simpleType` has been generated. */ -transform, - node(NS3,simpleType,SimpleType_ID,_SimpleType_Children,Attribute_ID), - json(SimpleType_ID,json(SimpleType_JSON)), - node(NS1,complexType,ComplexType_ID,_ComplexType_Children,_ComplexType_Parent_ID), - node(NS2,attribute,Attribute_ID,_Attribute_Children,ComplexType_ID), - node_attribute(Attribute_ID,name,Attribute_Name,_), - node_attribute(Attribute_ID,type,Unbound_Type,_), - node_attribute(Attribute_ID,use,Use,_), - node_attribute(Attribute_ID,fixed,Fixed,_), - node_attribute(Attribute_ID,default,Default,_) +transform(IName), + node(IName,NS3,simpleType,SimpleType_ID,_SimpleType_Children,Attribute_ID), + json(IName,SimpleType_ID,json(SimpleType_JSON)), + node(IName,NS1,complexType,ComplexType_ID,_ComplexType_Children,_ComplexType_Parent_ID), + node(IName,NS2,attribute,Attribute_ID,_Attribute_Children,ComplexType_ID), + node_attribute(IName,Attribute_ID,name,Attribute_Name,_), + node_attribute(IName,Attribute_ID,type,Unbound_Type,_), + node_attribute(IName,Attribute_ID,use,Use,_), + node_attribute(IName,Attribute_ID,fixed,Fixed,_), + node_attribute(IName,Attribute_ID,default,Default,_) ==> var(Unbound_Type), xsd_namespaces([NS1,NS2,NS3]) @@ -1408,7 +1426,7 @@ Use \= required, JSON2 = JSON1 ), - json(ComplexType_ID,json(JSON2)). + json(IName,ComplexType_ID,json(JSON2)). /** @@ -1418,13 +1436,13 @@ * As specified, `@name` and `@type` can not be both * present. */ -transform, - node(NS1,complexType,ComplexType_ID,_ComplexType_Children,_ComplexType_Parent_ID), - node(NS2,attribute,Attribute_ID,_Attribute_Children,ComplexType_ID), - node_attribute(Attribute_ID,ref,Ref,_), - node_attribute(Attribute_ID,use,Use,_), - node_attribute(Attribute_ID,fixed,_Fixed,_), - node_attribute(Attribute_ID,default,_Default,_) +transform(IName), + node(IName,NS1,complexType,ComplexType_ID,_ComplexType_Children,_ComplexType_Parent_ID), + node(IName,NS2,attribute,Attribute_ID,_Attribute_Children,ComplexType_ID), + node_attribute(IName,Attribute_ID,ref,Ref,_), + node_attribute(IName,Attribute_ID,use,Use,_), + node_attribute(IName,Attribute_ID,fixed,_Fixed,_), + node_attribute(IName,Attribute_ID,default,_Default,_) ==> xsd_namespaces([NS1,NS2]) | @@ -1446,7 +1464,7 @@ Use \= required, JSON2 = JSON1 ), - json(ComplexType_ID,json(JSON2)). + json(IName,ComplexType_ID,json(JSON2)). /** @@ -1456,13 +1474,13 @@ * therefore propagates a new `schema_definition` * constraint with @`Name` as name. */ -transform, - node(NS1,schema,Schema_ID,_Schema_Children,_Schema_Parent_ID), - node(NS2,attribute,Attribute_ID,_Attribute_Children,Schema_ID), - node_attribute(Attribute_ID,name,Attribute_Name,_), - node_attribute(Attribute_ID,type,Type_With_NS,_), - node_attribute(Attribute_ID,fixed,Fixed,_), - node_attribute(Attribute_ID,default,Default,_) +transform(IName), + node(IName,NS1,schema,Schema_ID,_Schema_Children,_Schema_Parent_ID), + node(IName,NS2,attribute,Attribute_ID,_Attribute_Children,Schema_ID), + node_attribute(IName,Attribute_ID,name,Attribute_Name,_), + node_attribute(IName,Attribute_ID,type,Type_With_NS,_), + node_attribute(IName,Attribute_ID,fixed,Fixed,_), + node_attribute(IName,Attribute_ID,default,Default,_) ==> \+var(Type_With_NS), xsd_namespaces([NS1,NS2]), @@ -1492,7 +1510,7 @@ Attribute_JSON3 = [default=Default_Casted|Attribute_JSON2] ), string_concat('@',Attribute_Name,Definition_Name), - schema_definition(Definition_Name,Attribute_ID,json(Attribute_JSON3)). + schema_definition(IName,Definition_Name,Attribute_ID,json(Attribute_JSON3)). /** @@ -1502,27 +1520,27 @@ /** * `xs:simpleType` which has a `xs:restriction` child. */ -transform, - node(NS1,simpleType,SimpleType_ID,_SimpleType_Children,_SimpleType_Parent_ID), - node(NS2,restriction,Restriction_ID,_Restriction_Children,SimpleType_ID), - json(Restriction_ID,Restriction_JSON) +transform(IName), + node(IName,NS1,simpleType,SimpleType_ID,_SimpleType_Children,_SimpleType_Parent_ID), + node(IName,NS2,restriction,Restriction_ID,_Restriction_Children,SimpleType_ID), + json(IName,Restriction_ID,Restriction_JSON) ==> xsd_namespaces([NS1,NS2]) | - json(SimpleType_ID,Restriction_JSON). + json(IName,SimpleType_ID,Restriction_JSON). /** * ########## XS:SCHEMA ########## */ -transform, - node(NS1,schema,Schema_ID,_Schema_Children,_Schema_Parent_ID), - node(NS2,element,Element_ID,_Element_Children,Schema_ID), - json(Element_ID,Element_JSON) +transform(IName), + node(IName,NS1,schema,Schema_ID,_Schema_Children,_Schema_Parent_ID), + node(IName,NS2,element,Element_ID,_Element_Children,Schema_ID), + json(IName,Element_ID,Element_JSON) ==> xsd_namespaces([NS1,NS2]) | - json(Schema_ID,Element_JSON). + json(IName,Schema_ID,Element_JSON). /** @@ -1530,14 +1548,14 @@ * `complexType` node which has the `@name` attribute * set. */ -transform, - node(NS1,complexType,ComplexType_ID,_ComplexType_Children,_ComplexType_Parent_ID), - json(ComplexType_ID,ComplexType_JSON), - node_attribute(ComplexType_ID,name,Definition_Name,_) +transform(IName), + node(IName,NS1,complexType,ComplexType_ID,_ComplexType_Children,_ComplexType_Parent_ID), + json(IName,ComplexType_ID,ComplexType_JSON), + node_attribute(IName,ComplexType_ID,name,Definition_Name,_) ==> xsd_namespaces([NS1]) | - schema_definition(Definition_Name,ComplexType_ID,ComplexType_JSON). + schema_definition(IName,Definition_Name,ComplexType_ID,ComplexType_JSON). /** @@ -1545,28 +1563,28 @@ * `simpleType` node which has the `@name` attribute * set. */ -transform, - node(NS1,simpleType,SimpleType_ID,_SimpleType_Children,_SimpleType_Parent_ID), - json(SimpleType_ID,SimpleType_JSON), - node_attribute(SimpleType_ID,name,Definition_Name,_) +transform(IName), + node(IName,NS1,simpleType,SimpleType_ID,_SimpleType_Children,_SimpleType_Parent_ID), + json(IName,SimpleType_ID,SimpleType_JSON), + node_attribute(IName,SimpleType_ID,name,Definition_Name,_) ==> xsd_namespaces([NS1]) | - schema_definition(Definition_Name,SimpleType_ID,SimpleType_JSON). + schema_definition(IName,Definition_Name,SimpleType_ID,SimpleType_JSON). /** * ########## ON BUILD_SCHEMA ########## */ -build_schema, - schema_definition(Name,_ID,Inline_Schema), - node(Namespace,schema,Schema_ID,_Schema_Children,_) +build_schema(IName), + schema_definition(IName,Name,_ID,Inline_Schema), + node(IName,Namespace,schema,Schema_ID,_Schema_Children,_) ==> xsd_namespace(Namespace), first_id(Schema_ID) | - json(Schema_ID,json([definitions=json([Name=Inline_Schema])])). + json(IName,Schema_ID,json([definitions=json([Name=Inline_Schema])])). /** @@ -1574,17 +1592,17 @@ */ /** - * get_json/2 - * get_json(ID,Unbound_Var) + * get_json/3 + * get_json(IName,ID,Unbound_Var) * - * Bind a variable to the content of the json/2 Constraint + * Bind a variable to the content of the json Constraint * with the same ID. * Usually used when finished to get the root's JSON. */ -:- chr_constraint get_json/2. +:- chr_constraint get_json/3. -json(ID,JSON) +json(IName,ID,JSON) \ - get_json(ID,Result) + get_json(IName,ID,Result) <=> - JSON = Result. \ No newline at end of file + JSON = Result. diff --git a/test/index.js b/test/index.js index fa257d8..d23dd62 100644 --- a/test/index.js +++ b/test/index.js @@ -1,7 +1,9 @@ +var fs = require('fs'); var xml2js = require('xml2js'); var JaySchema = require('jayschema'); require('should'); var _ = require('lodash'); +var temp = require('temp').track(); var js = new JaySchema(); @@ -32,9 +34,19 @@ describe('xsd2json', function() { var jsonSchema; it('should generate a json schema', function(done) { this.timeout(10000); - xsd2json.xsd2jsonWrapper(mergedSchemaStr, function(err, schema) { - jsonSchema = JSON.parse(schema); - done(err); + + temp.open('xsd2json2', function(err, info) { + if (err) return done(err); + + fs.write(info.fd, mergedSchemaStr); + fs.close(info.fd, function(err) { + if (err) return done(err); + + xsd2json.xsd2jsonWrapper(info.path, function(err, schema) { + jsonSchema = JSON.parse(schema); + done(err); + }); + }); }); });