I have input object that looks like this:
myObj = {
"Ob1": {
"myObjName": "A1",
"myObjType": "string",
"myObjOcc": "minOccurs="1""
"Ob2": {
"myObjName": "B1",
"myObjType": "string",
"myObjOcc": "minOccurs="1""
"Ob3": {
"myObjName": "C1",
"myObjType": "string",
"myObjOcc": "minOccurs="1""
}
}
}
"Ob4": {
"myObjName": "A2",
"myObjType": "string",
"myObjOcc": "minOccurs="1""
}
}
And I have to display the objects in xml schema way:
<xs:complexType name="A1" type="string" minOccurs="1">
<xs:complexType name="B1" type="string" minOccurs="1">
<xs:simpleType name="C1" type="string" minOccurs="1"/>
</complexType>
</complexType>
<xs:simpleType name="A2" type="string" minOccurs="1"/>
The idea is, if an object has child is a complexType if not, it's simpleType.
I have this code that is doing the printing, but if anyone can help me structure it with indent:
function isNestedObject(obj) {
for (var o in obj) {
if (isComplexType(o, obj)) {
return true;
}
}
}
function isComplexType(key, obj) {
return (typeof obj[key] === "object");
}
function xsdStructure(obj) {
var str = "",
properties = obj.properties;
if (isNestedObject(obj)) {
if (obj instanceof Array) {
for(var o in obj) {
xsdStructure(obj[o]);
}
}
str += "<xs:complexType name=\"" + obj.attrName + "\" type=\"" + obj.type + "\" " + obj.multiplicty + ">\n";
for (var key in obj) {
var arr = obj[key];
if (arr instanceof Array) {
for (var a in arr) {
str += xsdStructure(arr[a]);
}
}
}
str += "</xs:complexType>\n"
} else {
str = "<xs:simpleType name=\"" + obj.attrName + "\" type=\"" + obj.type + "\" " + obj.multiplicty + "/>\n";
}
return str;
}
function printing(myObj) {
var result = "";
for (var key in object) {
result += xsdStructure(object[key]);
}
result = '<xs:schema>\n'
+ result
+ '</xs:schema>';
return result;
}
It suppose to look like the above xml schema, but I can't use DOMParser so it has to be done manually.
Thanks in advance
I prepared fiddle for you. I had few things to mention for you. First, you should use the same attrs names among all you function which works with initial object. Ex: str += "<xs:complexType name=\"" + obj.myObjName + "\" type=\"" + obj.myObjType + "\" " + obj.myObjOcc + ">\n"; and NOT your str += "<xs:complexType name=\"" + obj.attrName + "\" type=\"" + obj.type + "\" " + obj.multiplicty + ">\n"; Also you will never get this condition true if (obj instanceof Array) because your obj doesn't contains arrays at all.
Related
{
field_country: ["England", "Netherlands", "India", "Italy"],
field_continent: ["Europe"],
field_group: ["Building", "People", "Landscape"
}
I want to loop over each item and return the key and the array together with ending 'OR' for example:
field_country: "England" OR field_country: "Netherlands"
The last item should not end with 'OR' in the loop. I am not sure what the best process is for this using vanilla JS. So far my code is as follows:
Object.keys(facets).forEach(function(facetKey) {
if (facets[facetKey].length > 1) {
facetResults = facets[facetKey];
for (var i = 0; i < facetResults.length; i ++) {
if (i == 1) {
filter = "'" + facetKey + "'" + ":'" + facetResults[i] + " OR";
return filter;
} else {
filter = "'" + facetKey + "'" + ":'" + facetResults[i];
}
}
} else {
filter = "'" + facetKey + "'" + ": " + facets[facetKey] + "'";
return filter;
}
});
I would be very grateful for any assistance.
Thanks in advance.
You can do something like this with Object.entries and Array.reduce if you would like to get the final result in the form of an object:
const data = { field_country: ["England", "Netherlands", "India", "Italy"], field_continent: ["Europe"], field_group: ["Building", "People", "Landscape"] }
const result = Object.entries(data).reduce((r, [k, v]) => {
r[k] = v.join(' OR ')
return r
}, {})
console.log(result)
It is somewhat unclear what is the final format you need to result in but that should help you to get the idea. If ES6 is not an option you can convert this to:
const result = Object.entries(data).reduce(function(r, [k, v]) {
r[k] = v.join(' OR ')
return r
}, {})
So there are is no arrow function etc.
The idea is to get the arrays into the arrays of strings and use the Array.join to do the "replacement" for you via join(' OR ')
Here's the idea. In your code you are appending " or " at the end of your strings starting at index 0. I suggest you append it at the the beginning starting at index 1.
var somewords = ["ORANGE", "GREEN", "BLUE", "WHITE" ];
var retval = somewords[0];
for(var i = 1; i< somewords.length; i++)
{
retval += " or " + somewords[i];
}
console.log(retval);
//result is: ORANGE or GREEN or BLUE or WHITE
Your conditional expression if (i == 1) would only trigger on the second iteration of the loop since i will only equal 1 one time.
Try something like:
if (i < (facetResults.length - 1)) {
// only add OR if this isn't the last element of the array
filter = "'" + facetKey + "'" + ":'" + facetResults[i] + " OR";
return filter;
}
Here's your updated code:
Object.keys(facets).forEach(function(facetKey) {
if (facets[facetKey].length > 1) {
facetResults = facets[facetKey];
for (var i = 0; i < facetResults.length; i ++) {
if (i < (facetResults.length - 1)) {
filter = "'" + facetKey + "'" + ":'" + facetResults[i] + " OR";
return filter;
} else {
filter = "'" + facetKey + "'" + ":'" + facetResults[i];
}
}
} else {
filter = "'" + facetKey + "'" + ": " + facets[facetKey] + "'";
return filter;
}
});
I'm turning a string into an object, then looping over that object. For some reason, if the string is semi-correctly formatted and I don't do the first two steps (replacing the parentheses with curly brackets) it works fine.
However, the replacement puts single ' instead of " (although it still parses without error). The parse misses putting the second id underneath the employeeType, and mistakenly puts it under employee.
https://codepen.io/MrMooCats/pen/zwpQGa
var str = "(id,created,employee(id,firstname,employeeType(id),lastname),location)";
str = str.replace(/[(]/g, "{"); // Possible problem line?
str = str.replace(/[)]/g, "}"); // Possible problem line?
str = str.replace(/([A-z])\s*{/g, "$1\":{");
str = str.replace(/([A-z])\s*([},])/g, "$1\":null$2");
str = str.replace(/({)/g, "{\"");
str = str.replace(/(,)/g, ",\"");
var objectStr = JSON.parse(str); // Object created, but wrong
var objectOutput = function(obj, counter) {
for(var i in obj) {
console.log(Array(counter+1).join("-") + " " + i);
if(obj.hasOwnProperty(i)){
if (obj[i] != null) {
objectOutput(obj[i], counter+1);
} else {
counter = 0;
}
}
}
};
objectOutput(objectStr, 0);
Actual output:
" id"
" created"
" employee"
"- id"
" firstname"
" employeeType"
"- id"
" lastname"
" location"
Expected Output
" id"
" created"
" employee"
"- id"
"- firstname"
"- lastname"
"- employeeType"
"-- id"
" location"
To get desired output you need to fix your objectOutput functrion:
// Works fine if the ( are { instead and remove the first two lines
var str = "(id,created,employee(id,firstname,employeeType(id),lastname),location)";
str = str.replace(/[(]/g, "{"); // Possible problem line?
str = str.replace(/[)]/g, "}"); // Possible problem line?
str = str.replace(/([A-z])\s*{/g, "$1\":{");
str = str.replace(/([A-z])\s*([},])/g, "$1\":null$2");
str = str.replace(/({)/g, "{\"");
str = str.replace(/(,)/g, ",\"");
var objectStr = JSON.parse(str); // Object created, but wrong
var objectOutput = function(obj, counter) {
for (var i in obj) {
console.log(Array(counter + 1).join("-") + " " + i);
if (obj.hasOwnProperty(i)) {
if (obj[i] != null) {
objectOutput(obj[i], counter + 1);
}
}
}
};
objectOutput(objectStr, 0);
I would also change regex this way:
var str = "(id,created,employee(id,firstname,employeeType(id),lastname),location)";
str = str.replace(/\(/g, "{").replace(/\)/g, "}");
str = str.replace(/([_a-zA-Z][_a-zA-Z0-9]*)\s*([,{}])/g, function(m, name, x){
return '"'+name+'":' + (x != '{' ? 'null' : '') + x;});
var objectStr = JSON.parse(str);
var objectOutput = function(obj, counter) {
for (var i in obj) {
console.log(Array(counter + 1).join("-") + " " + i);
if (obj.hasOwnProperty(i)) {
if (obj[i] != null) {
objectOutput(obj[i], counter + 1);
}
}
}
};
objectOutput(objectStr, 0);
I al using javascript and looping through the values of a submitted form and trying to build a son object out of the form values.
This is an example of the final object I need:
{
"DataObject": {
"user": { "-name": "username" },
"contentFile": {
"-filename": "Breaking_News",
"lock": { "-fileIsBeingEdited": "false" },
"content": {
"line": [
{
"-index": "1",
"-text": "this is the header"
},
{
"-index": "2",
"-text": "this is the first line"
},
{
"-index": "3",
"-text": "this is the second line"
}
]
}
}
}
}
So far i am adding all of this data to a string as that seems to be the only way i can insert the form values (the line array) into the middle of the object.
var jsonStr = '{'
+ 'iceteaDataObject: {'
+ 'user: {"-name": "hindsc52"},'
+ 'contentFile: {'
+ '"-filename": "Ticker",'
+ 'lock: { "-fileIsBeingEdited": "false" },'
+ 'content: {'
+ 'line: ['
for(var i = 0; i < elem.length; i++) {
if(!elem[i].value == '') {
jsonStr += '{'
jsonStr += "-index: " + i + ',';
jsonStr += "-text: " + elem[i].value;
jsonStr += '},'
}
}
jsonStr += ']}}}}';
console.log(JSON.parse(jsonData));
however when running this I get the error: unexpected token 'i'.
I have tried to use stringily but then just outputs the entire sting again.
You don't need or want JSON for this, just build the object:
// Sample data
var elem = [{
value: "one"
}, {
value: "two"
}];
// Build the object
var obj = {
"DataObject": {
"user": {
"-name": "username"
},
"contentFile": {
"-filename": "Breaking_News",
"lock": {
"-fileIsBeingEdited": "false"
},
"content": {
"line": []
}
}
}
};
var line = obj.DataObject.contentFile.content.line;
elem.forEach(function(entry, index) {
if (entry.value != '') {
line.push({
"-index": index,
"-text": entry.value
});
}
});
// Show result:
document.body.innerHTML =
"<pre>" +
JSON.stringify(obj, null, 2) +
"</pre>";
Side note: You don't check for blank strings like this:
if (!entry.value == '') { // <== Incorrect
You can use:
if (entry.value != '') {
or:
if (entry.value) {
You shouldn't build JSON like this, but use JSON.stringify() (see MDN doc) instead:
var myObject={foo:"bar"};
var myJSON=JSON.stringify(myObject);
console.log(myJSON); //echo {"foo":"bar"}
Here is an alternative way:
var json = {
iceteaDataObject: {
"-name": "hindsc52"
},
contentFile: {
"-filename": "Ticker",
lock: { "-fileIsBeingEdited": "false" },
content: {line: []}
}
}
for(var i = 0; i < elem.length; i++) {
if(!elem[i].value == '') {
json.contentFile.content.line.push({"-index": i,"-text": elem[i].value }
}
}
var jsonStr = JSON.stringify(json);
You need to put all your keys in quotes for this to work. As the others have pointed out though, you are not really supposed to do this.
If you still want to do it your way, try this:
var jsonStr = '{'
+ '"iceteaDataObject": {'
+ '"user": {"-name": "hindsc52"},'
+ '"contentFile": {'
+ '"-filename": "Ticker",'
+ '"lock": { "-fileIsBeingEdited": "false" },'
+ '"content": {'
+ '"line": ['
for(var i = 0; i < elem.length; i++) {
if(!elem[i].value == '') {
jsonStr += '{'
jsonStr += '"-index": ' + i + ',';
jsonStr += '"-text": ' + '"' + elem[i].value + '"';
jsonStr += '},'
}
}
jsonStr += ']}}}}';
I'm trying to parse JSON in JavaScript. If my JSON data looks like below, I want to iterate through all the JSON elements that start with "custom" and not with any other string. How do I do this?
{
"fields": {
"custom12": {
value: "dsada"
},
"custom45": {
value: "adsadad"
},
"test12": {
value: "12323"
}
}
}
var newObject = {}, key;
for(key in data.fields){
if(key.search(/custom/) > -1){
newObject[key] = data.fields[key];
}
}
console.log(newObject);
The following iterates the properties of the fields object and checks whether the property's name contains custom:
var data = yourObjectLiteral, i, current;
for(i in data.fields) {
if(i.indexOf('custom') > -1) {
current = data.fields[i];
// ... your logic ...
}
}
With the json string you provided I'd do it as such:
<script src="json2.js"></script>
<script>
var raw = '{'
+ ' "fields": {'
+ ' "custom12": {'
+ ' "value": "dsada"'
+ ' },'
+ ' "custom45": {'
+ ' "value": "adsadad"'
+ ' },'
+ ' "test12": {'
+ ' "value": "12323"'
+ ' }'
+ ' }'
+ '}';
var data = JSON.parse(raw);
var fields = data.fields;
var message = '';
for (var key in fields) {
if (key.indexOf('custom') === 0) {
message += key + ': ' + fields[key].value + '\n';
}
}
alert(message);
</script>
But, if you can rewrite the incomming message a little it will look simpler.
<script src="json2.js"></script>
<script>
var raw = '{'
+ ' "custom12": "dsada",'
+ ' "custom45": "adsadad",'
+ ' "test12": "12323"'
+ '}';
var fields = JSON.parse(raw);
var message = '';
for (var key in fields) {
if (key.indexOf('custom') === 0) {
message += key + ': ' + fields[key] + '\n';
}
}
alert(message);
</script>
Is there something like Java's reflection where I can know what attributes are available?
for(var key in myObject) {
//do something with key
}
that enumerates through all properties
all properties for the window object http://jsfiddle.net/KdyLG/
This is one function that I use. You can specify which level of the array you which to dump.
alert(dump(myArray));
function dump(arr,level) {
var dumped_text = "";
if(!level) level = 0;
//The padding given at the beginning of the line.
var level_padding = "";
for(var j=0;j<level+1;j++) level_padding += " ";
if(typeof(arr) == 'object') { //Array/Hashes/Objects
for(var item in arr) {
var value = arr[item];
if(typeof(value) == 'object') { //If it is an array,
dumped_text += level_padding + "'" + item + "' ...\n";
dumped_text += dump(value,level+1);
} else {
dumped_text += level_padding + "'" + item + "' => \"" + value + "\"\n";
}
}
} else { //Stings/Chars/Numbers etc.
dumped_text = "===>"+arr+"<===("+typeof(arr)+")";
}
return dumped_text;
}
A way to do it:
for(var attrib in myObject){
if(typeof attrib != 'function') {
alert('this is attribute ' + attrib + 'with value' + myObject[attrib]);
} }