JSONIX how to have a strong XML Validation - json

I just tried to run the JSONIX sample purchase order.
I did it like it was mentioned on the Highscore WebSite.
What makes me wonder was this sample bases on the use of a XSD, the validation of the incoming XML is used for elements with child nodes but not for simple tags.
This will show an error:
... <item_will_cause_error partNum="926-AA">
<productName>Baby Monitor</productName>
<quantity>1</quantity>
<USPrice>39.98</USPrice>
<shipDate>1999-05-21</shipDate>
... </item_will_cause_error>
This not:
... <item partNum="926-AA">
<productName>Baby Monitor</productName>
<quantity_will_cause_error>1</quantity_will_cause_error>
<USPrice>39.98</USPrice>
<shipDate>1999-05-21</shipDate>
... </item>
So, is it possible to switch on a strong validation, because <quantity_will_cause_error>is not a valid element.
Kind regards
Markus

now I use this
var Jsonix = require('jsonix').Jsonix;
//Include or require PO.js so that PO variable is available
//For instance, in node.js:
var PO = require('./mappings/PO').PO;
//First we construct a Jsonix context - a factory for unmarshaller
//(parser)
//and marshaller (serializer)
var context = new Jsonix.Context([ PO ]);
//Then we create a unmarshaller
var unmarshaller = context.createUnmarshaller();
//Unmarshal an object from the XML retrieved from the URL
var fs = require('fs');
var Ajv = require('ajv');
var XMLSchemaJsonSchema =
JSON.parse(fs.readFileSync(
'./node_modules/jsonix/jsonschemas/w3c/2001/XMLSchema.jsonschema')
.toString());
var JsonixJsonSchema = JSON.parse(fs.readFileSync(
'./node_modules/jsonix/jsonschemas/jsonix/Jsonix.jsonschema')
.toString());
var POJsonSchema = JSON.parse(fs.readFileSync(
'./mappings/PO.jsonschema').toString());
var ajv = new Ajv();
ajv.addSchema(XMLSchemaJsonSchema,
'http://www.jsonix.org/jsonschemas/w3c/2001/XMLSchema.jsonschema');
ajv.addSchema(JsonixJsonSchema,
'http://www.jsonix.org/jsonschemas/jsonix/Jsonix.jsonschema');
var validate = ajv.compile(POJsonSchema);
unmarshaller.unmarshalFile('./po.xml',
//This callback function will be provided
//with the result of the unmarshalling
function (unmarshalled) {
var po_ = unmarshalled;
var valid = validate(po_);
if (!valid) {
console.log('Validation failed.');
console.log('Validation errors:');
console.log(validate.errors);
}
});
The Result looks like this:
Validation failed.
Validation errors:
[ { keyword: 'type',
dataPath: '.value.items.item[1].shipDate.timezone',
schemaPath: '#/definitions/integer/type',
params: { type: 'integer,null' },
message: 'should be integer,null' },
{ keyword: 'type',
dataPath: '.value.items.item[1].shipDate',
schemaPath: '#/anyOf/1/type',
params: { type: 'null' },
message: 'should be null' },
{ keyword: 'anyOf',
dataPath: '.value.items.item[1].shipDate',
schemaPath: '#/anyOf',
params: {},
message: 'should match some schema in anyOf' },
{ keyword: 'enum',
dataPath: '.name.localPart',
schemaPath: '#/anyOf/1/properties/name/allOf/1/properties/localPart/enum',
params: { allowedValues: [Object] },
message: 'should be equal to one of the allowed values' },
{ keyword: 'anyOf',
dataPath: '',
schemaPath: '#/anyOf',
params: {},
message: 'should match some schema in anyOf' } ]
But this make me again wonder: dataPath: '', an error on the root ???

Related

Getting only value of custom fields in Google Suite User list

I have made Custom Fields in my Users in Google Suite.
Category: Foresatt
Among them:
Name: 'foresatt epost', type:email, number: multiple values
I would like to list these values using Google Script. I used this:
https://developers.google.com/admin-sdk/directory/v1/quickstart/apps-script
To write this code:
function listUsers() {
var optionalArgs = {
customer: 'my_customer',
maxResults: 10,
orderBy: 'email',
projection: 'custom',
customFieldMask:'Foresatt'
};
var response = AdminDirectory.Users.list(optionalArgs);
var users = response.users;
if (users && users.length > 0) {
Logger.log('Users:');
for (i = 0; i < users.length; i++) {
var user = users[i];
var foresatt = user.customSchemas;
Logger.log('%s (%s)', user.primaryEmail, user.name.fullName, foresatt);
}
} else {
Logger.log('No users found.');
}
}
That works, but I would like to get only the values. What I get now:
{Foresatt={
foresatt_mob=[{value=X#X#X#X#, type=work}, {type=work, value=X#X#X#X#}, {type=work, value=X#X#X#X#}],
foresatt_epost=[{value=xx#xx.no, type=work}, {type=work, value=xy#xx.no}, {value=yy#xx.no, type=work}],
foresatt_navn=[{type=work, value=Xx}, {value=Xy, type=work}, {type=work, value=Yy}]
}
}
What I would like to get: xx#xx.no, xy#xx.no, yy#xx.no
I have tried several things, but I'm afraid I'm not experienced enough.
var epost = foresatt.foresatt_epost;
Results in: TypeError: Cannot read property 'foresatt_epost'
var epost = foresatt('foresatt_epost');
Results in: TypeError: foresatt is not a function
Please advise me, how do I get only the values fram the field 'foresatt epost'?
I believe your goal as follows.
You want to retrieve the values of xx#xx.no, xy#xx.no, yy#xx.no from the following object:
const object = {
Foresatt: {
foresatt_mob: [
{ value: "X#X#X#X#",type: "work"},
{ value: "X#X#X#X#",type: "work"},
{ value: "X#X#X#X#",type: "work"},
],
foresatt_epost: [
{ value: "xx#xx.no", type: "work"},
{ value: "xy#xx.no", type: "work"},
{ value: "yy#xx.no", type: "work"},
],
foresatt_navn: [
{ type: "work", value: "Xx"},
{ type: "work", value: "Xy"},
{ type: "work", value: "Yy"},
]
}
}
In this case, the values can be retrieved from the object.Foresatt.foresatt_epost array.
Sample script:
const object = {}; //Your object
const res = object.Foresatt.foresatt_epost.map(e => e.value);
console.log(res) // Outputs: [ 'xx#xx.no', 'xy#xx.no', 'yy#xx.no' ]
If user.customSchemas is the above object, the script is as follows.
var foresatt = user.customSchemas;
const res = foresatt.Foresatt.foresatt_epost.map(e => e.value);
console.log(res)
If you want to retrieve the value as a comma separated string, you can use res.join(",").
References:
map()
Note:
If there is no guarantee your property will exist in your object, you can do (object.property||[]).map(...) instead of object.property.map(...) to avoid the error Uncaught TypeError: Cannot read property 'forEach' of undefined.

json.stringify return value

I'm trying to get datatypes of a JSON.stringify to compare them.
I had used:
var id = d.patogeno;
alert(id);
But it tell the alert that is not defined.
I got this database:
var IDData = JSON.stringify([
["node/9837102", "node/26794", "Customer", "patongenoA", "1412451.0", 3, 520, "1412381"],
["node/9837102", "node/44210", "Customer", "patongenoB", "1436765.0", 2, 384, "1436693"],
]);
and the following function:
function createNodes(startnodes, endnodes, startnodetype, endnodetype, PayTime, TXN_COUNT, Total_Amt, SendTime) {
var node_set = new Set();
var links = [];
var nodetype = d3.set();
startnodes.forEach(function(src, i) {
var tgt = endnodes[i];
node_set.add({
id: src,
type: startnodetype[i]
});
node_set.add({
id: tgt,
type: endnodetype[i]
});
links.push({
source: src,
target: tgt,
paytime: PayTime[i],
patogeno: TXN_COUNT[i], // cambio ---- variable con cual trabajar
total_amt: Total_Amt[i],
SendTime: SendTime[i],
value: 1
});
});
I need to know the value of every patogeno and return it to compare it. Is there a way to do it?, or How to return a specific value, for example: "patogenoB" from IDData?
First, JSON.stringify produces a string.
const obj = {example: 5}
const str = JSON.stringify(obj)
console.log(typeof str) // 'string'
If you want an addressable object, you would do the reverse to a string:
const str = '{"example": 5}'
const obj = JSON.parse(str)
console.log(obj.example) // 5
I do not know how to answer your question with respect to JSON.stringify, nor do I understand why you would be turning an array of arrays into a string instead of converting them into addressable objects, but at the very end of createNodes, you would be able to do this:
links.forEach((d) => console.log(d.patogeno))

Immutable.js add new data

I want to save all the searches from the user as a key of objects (search field):
beforeState = fromJS({
showFilter: false,
loading: false,
error: false,
search: fromJS({})
})
afterState = fromJS({
showFilter: false,
loading: false,
error: false,
search:
key1: [{}, {},...],
key2: [{}, {}, {}...]
})
New data:
const searchText = 'test'
const data = [{object1}, {object2},....]
const expectedResult = state
search has to be immutable as it can change. key1, key2... doesn't need to, as once they're initilised won't change.
Two questions:
I think I need fromJS function in searchKey in order to get a map, I mean, fromJS function does not nest maps
var t = beforeState.get('search').constructor.name;
console.log(t) //gets Map but without fromJS gets Object
But as array inside key1, key2, can't mutate, another fromJS would't be needed. Is it that way?
How can I insert key1, key2.. values inside search field?
Using mergeDeep, seems to be ok:
var boxes = Immutable.fromJS({
box1: {
id:1
},
box2: {
id:2
},
search: Immutable.fromJS({box3: {z:7}})
});
var data = Immutable.fromJS({
search: {
box3: {id:3}
}
});
var newBoxes = boxes.mergeDeep(data);
console.log(newBoxes.get('search').toJS());

Defining a Mongoose schema from a JSON file

I want to define my mongoose schema from JSON file. This is my JSON file structure:
{
"default": [
{
"item": "productTitle",
"label": "Product Title",
"note": "e.g Samsung GALAXY Note 4",
"type": "text",
"required": "Product Name cannot be blank..."
},
{
"item": "productCode",
"label": "Product Code",
"type": "text",
"required": "Product Code cannot be blank..."
}
]}
This is my node.js model:
// Load the module dependencies
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
var fs = require('fs');
var file = __dirname + '/product.server.model.json';
// Read the json file
fs.readFile(file, 'utf8', function (err, data) {
data = JSON.parse(data);
var productJson = {};
for(var i = 0; i < data.default.length; i++) {
productJson[data.default[i].slug] = {
type: 'String',
required: data.default[i].required,
default: '',
trim: true
}
}
});
// Define a new 'ProductSchema'
var ProductSchema = new Schema(
// Here I want to put JSON Data 'productJson'
);
// Create the 'Product' model out of the 'ProductSchema'
mongoose.model('Product', ProductSchema);
I tried every possible way to define mongoose schema from JSON data 'productJson'. But unless I pre-define my mongoose schema, it is not working. Is there any way to define mongoose schema from JSON data in my model? Any suggestion please?
fs.readFile is an asynchronous function which means that it returns immediately and then later provides its results to the caller via the callback function that you provide as the third parameter.
As such, you need to hold off on using productJson until its populated within that callback. That means moving your schema and model creation inside the callback as well.
fs.readFile(file, 'utf8', function (err, data) {
data = JSON.parse(data);
var productJson = {};
for(var i = 0; i < data.default.length; i++) {
// Changed .slug to .item here as I don't see slug in the JSON
productJson[data.default[i].item] = {
type: 'String',
required: data.default[i].required,
default: '',
trim: true
}
}
// Define a new 'ProductSchema'
var ProductSchema = new Schema(productJson);
// Create the 'Product' model out of the 'ProductSchema'
mongoose.model('Product', ProductSchema);
});
Another alternative you can use here is to use the synchronous fs.readFileSync method to read the file instead. This is helpful in startup/initialization cases like this where your application as a whole shouldn't proceed until this file is processed.
var data = fs.readFileSync(file, 'utf8');
data = JSON.parse(data);
var productJson = {};
for(var i = 0; i < data.default.length; i++) {
// Changed .slug to .item here as I don't see slug in the JSON
productJson[data.default[i].item] = {
type: 'String',
required: data.default[i].required,
default: '',
trim: true
}
}
// Define a new 'ProductSchema'
var ProductSchema = new Schema(productJson);
// Create the 'Product' model out of the 'ProductSchema'
mongoose.model('Product', ProductSchema);

ServiceStack.Text.JsonObject.Parse vs. NewtonSoft.Json.Linq.JObject.Parse for nested tree of 'dynamic' instances?

I'd like to try ServiceStack's json parsing, but I've already figured out how to do something I need via Newtonsoft. Can this same thing by done via ServiceStack?
I've tried with the commented out code but it gives exceptions, see below for exception details.
Thanks!
Josh
[Test]
public void TranslateFromGitHubToCommitMessage()
{
const string json =
#"
{
'commits':
[
{
'author': {
'email': 'dev#null.org',
'name': 'The Null Developer'
},
'message': 'okay i give in'
},
{
'author': {
'email': 'author#github.com',
'name': 'Doc U. Mentation'
},
'message': 'Updating the docs, that\'s my job'
},
{
'author': {
'email': 'author#github.com',
'name': 'Doc U. Mentation'
},
'message': 'Oops, typos'
}
]
}
";
dynamic root = JObject.Parse(json);
//dynamic root = ServiceStack.Text.JsonSerializer.DeserializeFromString<JsonObject>(json);
//dynamic root = ServiceStack.Text.JsonObject.Parse(json);
var summaries = new List<string>();
foreach (var commit in root.commits)
{
var author = commit.author;
var message = commit.message;
summaries.Add(string.Format("{0} <{1}>: {2}", author.name, author.email, message));
}
const string expected1 = "The Null Developer <dev#null.org>: okay i give in";
const string expected2 = "Doc U. Mentation <author#github.com>: Updating the docs, that's my job";
const string expected3 = "Doc U. Mentation <author#github.com>: Oops, typos";
Assert.AreEqual(3, summaries.Count);
Assert.AreEqual(expected1, summaries[0]);
Assert.AreEqual(expected2, summaries[1]);
Assert.AreEqual(expected3, summaries[2]);
}
Exceptions Detail
When using the first commented out line:
dynamic root = ServiceStack.Text.JsonSerializer.DeserializeFromString<JsonObject>(json);
This exception occurs when the method is called.
NullReferenceException:
at ServiceStack.Text.Common.DeserializeListWithElements`2.ParseGenericList(String value, Type createListType, ParseStringDelegate parseFn)
at ServiceStack.Text.Common.DeserializeEnumerable`2.<>c__DisplayClass3.<GetParseFn>b__0(String value)
at ServiceStack.Text.Common.DeserializeSpecializedCollections`2.<>c__DisplayClass7. <GetGenericEnumerableParseFn>b__6(String x)
at ServiceStack.Text.Json.JsonReader`1.Parse(String value)
at ServiceStack.Text.JsonSerializer.DeserializeFromString[T](String value)
at GitHubCommitAttemptTranslator.Tests.GitHubCommitAttemptTranslatorTests.TranslateFromGitHubToCommitMessage()
And, the second:
dynamic root = ServiceStack.Text.JsonObject.Parse(json);
var summaries = new List<string>();
foreach (var commit in root.commits) // <-- Happens here
'ServiceStack.Text.JsonObject' does not contain a definition for 'commits'
Note: the message is 'string' does not contain a definition for 'commits' if I use code from line one, but change the type to or to instead of
at CallSite.Target(Closure , CallSite , Object )
at System.Dynamic.UpdateDelegates.UpdateAndExecute1[T0,TRet](CallSite site, T0 arg0)
at GitHubCommitAttemptTranslator.Tests.GitHubCommitAttemptTranslatorTests.TranslateFromGitHubToCommitMessage()
After using DynamicJson from .NET 4.0 ServiceStack
Referring to mythz's comment:
This test case works, but if I modify it like below:
var dog = new { Name = "Spot", Parts = new { Part1 = "black", Part2 = "gray" }, Arr = new [] { "one", "two", "three"} };
var json = DynamicJson.Serialize(dog);
var deserialized = DynamicJson.Deserialize(json);
Then, deserialized.Name and Parts are fine, but Arr is of type string.
Also:
If I use ' quotes it doesn't appear to work. Is that normal? json2 works (to the degree that Arr is also still a string), but json3 does not work at all. It just returns
Immediate Window:
deserialized = DynamicJson.Deserialize(json3);
{}
base {System.Dynamic.DynamicObject}: {}
_hash: Count = 1
----- code: -----
var json2 =
#"
{
""Name"": ""Spot"",
""Parts"": {
""Part1"": ""black"",
""Part2"": ""gray""
},
""Arr"": [
""one"",
""two"",
""three""
]
}";
var json3 =
#"
{
'Name': 'Spot',
'Parts': {
'Part1': 'black',
'Part2': 'gray'
},
'Arr': [
'one',
'two',
'three'
]
}";
var deserialized = DynamicJson.Deserialize(json1);
ServiceStack's JSON Serializer also supports dynamic parsing, see examples of how to parse GitHub's JSON in the Dynamic JSON section of the wiki page.