Decode Xml to mxGraph .Net - mxgraph

I want to execute an operation that is an inversion of what i do when forming xmlString in mxGraph().
mxGraph graph = new mxGraph();
Object parent = graph.GetDefaultParent();
graph.Model.BeginUpdate();
try
{
Object v1 = graph.InsertVertex(parent, null, "Hello,", 20, 20, 80, 30);
Object v2 = graph.InsertVertex(parent, null, "World!", 200, 150, 80, 30);
Object e1 = graph.InsertEdge(parent, null, "Edge", v1, v2);
}
finally
{
graph.Model.EndUpdate();
}
mxCodec codec = new mxCodec();
Xml = mxUtils.GetXml(codec.Encode(graph.Model));
var xmlString = mxUtils.GetXml(xml);
I'm trying to execute inverse operation.
XmlDocument doc = mxUtils.ParseXml(xmlString);
mxGraph graphNew = new mxGraph();
var decoder = new mxCodec(doc);
decoder.Decode(doc, graphNew.Model);
Object parentNew = graphNew.GetDefaultParent();
But the object "parentNew" has no children.

this code:
decoder.Decode(doc, graphNew.Model);
should be replaced with this code below:
decoder.Decode(doc.DocumentElement, graphNew.Model);

I just encountered this myself and was able to solve it.
decoder.Decode(doc, graphNew.Model);
should be:
decoder.Decode(doc.DocumentElement, graphNew.getModel());
In addition to doc.DocumentElement, you also need to use graphNew.getModel(), not just graphNew.model.
As per this documentation
Also, you do not need to create a new graph. Insert your existing graph into the second parameter of Decode.

Related

Convert and parse json string to key value pairs using NewtonSoft

Trying to convert a json string to key value pairs using Newtonsoft but no luck so far.
Response from the API:
var response = #"{'result':{'0199 - B344EE33':
{
'6400_00260100':{'1':[{'val':336688}]},
'6400_00462500':{'1':[{'val':null}]},
'6800_00832A00':{'1':[{'low':3000,'high':3000,'val':3000}]},
'6800_008AA200':{'1':[{'low':0,'high':null,'val':0}]}
}}}";
Result I want is a new object of key value pairs:
{
"6400_00260100" : 336688,
"6400_00462500" : null,
"6800_00832A00" : 3000,
"6800_008AA200" : 0
}
In the response the result will always be the first and only prop. In the next level the code 0199 - B344EE33 can change but there will be only one prop in this level so we can always take the first one. Then in the last level we always need the val property.
What I have is the following but for getting the key value pairs in a clean way I got stuck:
var json = JObject.Parse(response);
var result = json["result"].First;
var path = result.Path;
UPDATE
var jObjectResult = new JObject();
var response = #"{'result':{'0199 - B344EE33':
{
'6800_10821E00':{'1':[{'val':'SMA Sunny Boy'}]},
'6800_00A21E00':{'1':[{'val':'3.0.0.2222'}]},
'6800_00823400':{'1':[{'low':3000,'high':3000,'val':3000}]},
'6800_08822B00':{'1':[{'val':'SMA'}]},
'6800_08822000':{'1':[{'val':'Sunny Boy 3.0'}]}
}}}";
var json = JObject.Parse(response);
var json_serial = json["result"].First.Children<JObject>().ToList()[0];
foreach(var token in json_serial)
{
var tokenKey = token.Key;
var tokenVal = token.Value.SelectToken("$.1[0].val");
jObjectResult.Add(tokenKey, tokenVal);
}
You could use SelectTokens with the recursive descent operator .. to find all the val properties, then walk up the chain using .Parent repeatedly to get the corresponding key. Create new JProperties from this information and put them into a new JObject to get your result. Here is a "one-liner":
var result = new JObject(
JObject.Parse(response)
.SelectTokens("$..val")
.Select(jt => new JProperty(
((JProperty)jt.Parent.Parent.Parent.Parent.Parent.Parent).Name,
jt
))
);
Fiddle: https://dotnetfiddle.net/TbZ7LS
At the end with some pointers form #Brian Rogers I came with the following solution:
// Arrange
var response = #"{'result':{'0199 - B344EE33':
{
'6800_10821E00':{'1':[{'val':'SMA Sunny Boy'}]},
'6800_00A21E00':{'1':[{'val':'3.0.0.2222'}]},
'6800_00823400':{'1':[{'low':3000,'high':3000,'val':3000}]},
'6800_08822B00':{'1':[{'val':'SMA'}]},
'6800_08822000':{'1':[{'val':'Sunny Boy 3.0'}]}
}}}";
// Act
var json = JObject.Parse(response);
var json_serial = (JProperty)json["result"].First();
var jObjectResult = new JObject(
json_serial.Value.Select(p =>
{
return new JProperty(
((JProperty)p).Name,
p.First.SelectToken("$.1[0].val")
);
}));

How to get property from JSON model filled with oData?

Im trying to get property from oData return model. I set data in success callback function from oData to JSON model.
oODataModel.read("/ConnObjSet?$filter=Objecttype eq 'CONNOBJ' and ConnObject eq '20000000002'",
true,
true,
false,
function _OnSuccess(oData, oResponse){
var oJSON = new sap.ui.model.json.JSONModel();
oJSON.setData(oData);
sap.ui.getCore().setModel(oJSON, "ConnectionObject");
},
This is my JSON object in console log and highlighted property I want to get. I want to get every 15 Buspartner number from whole array.
And this is what I tried to get property:
var oLog = sap.ui.getCore().getModel("ConnectionObject").oData.results;
console.log(oLog);
If you have an array of objects, you can get an array of properties from each of these objects by using the Array.map() function.
So in your case:
var aResults = this.getView().getModel().getProperty("/results");
var aBuspartner = aResults.map(function (r) { return r.Buspartner});
var oJSONModel = new sap.ui.model.json.JSONModel();
oJSONModel.setProperty("/resultarray", aBuspartner)
Please try:
var aResults = this.getView().getModel().getProperty("/results");
var oJSONModel = new sap.ui.model.json.JSONModel();
oJSONModel.setProperty("/resultarray",new Array())
for(var i = 0; i<aResults.lenght;i++){
oJSONModel.getProperty("/resultarray").push(aResults[i].Buspartner)
}
You could also try to add a filter and select to your oData.read
The oData-URL
http://services.odata.org/V2/Northwind/Northwind.svc/Products
selects all Product with all their properties
http://services.odata.org/V2/Northwind/Northwind.svc/Products?$filter=UnitsInStock%20eq%2017
shows only Products with "UnitsInStock=17"
http://services.odata.org/V2/Northwind/Northwind.svc/Products?$select=ProductID&$filter=UnitsInStock%20eq%2017
selects only the ProductID of Products with "UnitsInStock=17"
so
oODataModel.read("/ConnObjSet?$select=Buspartner&$filter=Objecttype eq 'CONNOBJ' and ConnObject eq '20000000002'"
...
should get the filtered Buspartners directly.

How to access an object in AS3

I wrote this code
var enemies:Object = new Object();
// HP MP ATK DEF MATK MDEF AGI LUCK
enemies.Goblin = [40, 20, 6, 6, 3, 3, 4, 1];
which contains those stats for the goblin and I created a function that should take the stats from enemies.Goblin and put them in some variables but it won't work.
function createEnemy(enemyName:String):void {
e_hp = enemies.enemyName[0];
e_mp = enemies.enemyName[1];
e_atk = enemies.enemyName[2];
e_def = enemies.enemyName[3];
e_matk = enemies.enemyName[4];
e_mdef = enemies.enemyName[5];
e_agi = enemies.enemyName[6];
e_luck = enemies.enemyName[7];
}
This is the output error when the createEnemy function is executed: TypeError: Error #1010: A term is undefined and has no properties.
Object "enemies" does not have "enemyName" property.
Try this:
enemies[enemyName][0]
enemies[enemyName][1]
...
The answer had been given but what are you doing is a wrong way to do. Accessing properties by index is asking for trouble in a very near future.
It is better to do with classes but since you're using objects, I will try use objects too:
var goblin_stats:Object = { hp:40, mp:20, atk:6, def:6 }; // and so on
var elf_stats:Object = { hp:35, mp:30, atk:8, def:4 }; // and so on
...
// add as much characters as needed
Now I believe you just want to create a fresh goblin based on goblin stats. Just pass the stats to the createEnemy function:
createEnemy(goblin_stats);
function createEnemy(stats:Object):void {
e_hp = stats.hp;
e_mp = stats.mp;
// and so on
}
or better:
function createEnemy(stats:Object):void {
for (var property:String in stats) e_stats[property] = stats[property];
}
Store objects (everything) in arrays for easy referencing. Here are the key code:
var aEnemies:Array = new Array();
var mcEnemy:Object = new Object();
mcEnemy.iHP = 40; // set iHP property to 40
aEnemies.push(mcEnemy); // add enemy to array of enemies
trace("enemy 0's HP: " + aEnemies[0].iHP);

“Padding is invalid and cannot be removed” using AesManaged

I am getting error "Padding is invalid and cannot be removed."
when trying to decrypt file contents in chunks(using buffer). I am able to decrypt whole file at once but not in blocks. I found many links regarding this problem and most of them suggested to set Padding of AesManaged object
like aesManaged.Padding = PaddingMode.None
But this property is not available in window phone application.
Below is method:
internal static byte[] DecryptBytes(byte[] cipherText, string password)
{
// Check arguments.
if (cipherText == null || cipherText.Length <= 0)
throw new ArgumentNullException("cipherText");
byte[] decryptedBytes= new byte[cipherText.Length];
using (var rijAlg = new AesManaged { KeySize = 256, BlockSize = 128 })
{
var key = new Rfc2898DeriveBytes(password, Encoding.UTF8.GetBytes(Salt));
rijAlg.Key = key.GetBytes(rijAlg.KeySize / 8);
rijAlg.IV = key.GetBytes(rijAlg.BlockSize / 8);
// Create a decrytor to perform the stream transform.
ICryptoTransform decryptor = rijAlg.CreateDecryptor(rijAlg.Key, rijAlg.IV);
// Create the streams used for decryption.
using (var msDecrypt = new MemoryStream())
{
using (var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Write))
{
csDecrypt.Write(cipherText, 0, cipherText.Length);
csDecrypt.FlushFinalBlock();
}
decryptedBytes = msDecrypt.ToArray();
}
}
return decryptedBytes;
}
Please suggest issue in above code or any other workaround
Don't use aesManaged.Padding = PaddingMode.None it will only hide the error, not solve it. You would get the error for incorrectly derived keys, incorrect ciphertext or - for smaller ciphertext - incorrect IV.
Print out the values of all the inputs in hexadecimals right before you perform the decrypt, then compare them with the ones obtained for encryption.

Javascript: Array overriding the same values after assinging to JSON object

I am working with jquery ajax & the ajax response is multidimensional json array, I am assinging the JSON values to coordinates array & then assinging coordinates array to new JSON coord_set, after assinging all values to coord_set, It takes last array values to all,
for e.g.
the JSON result contains following values
obj[0]={125, 343, 456, 453},
obj[1]={345, 657, 234, 787},
obj[2]={980, 677, 657, 568}
after assinging to new JSON the values are:
coord_set[0] = {
fillColor : 'rgba(255, 234, 111 ,0.5)',
data : [980, 677, 657, 568]
}
coord_set[1] = {
fillColor : 'rgba(255, 234, 111 ,0.5)',
data : [980, 677, 657, 568]
}
coord_set[2] = {
fillColor : 'rgba(255, 234, 111 ,0.5)',
data : [980, 677, 657, 568]
}
This is my code:
var obj = JSON.parse(data);
for(var j=0;j<obj.length;j++)
{
for (var i=0;i<obj[j].length;i++)
{
coordinates[i] = obj[j][i].how_many;
}
coord_set[j] = { fillColor : 'rgba(255, 234, 111 ,0.5)', data : coordinates };
}
alert(JSON.stringify(coord_set));
Please tell me, If I am doing Anything wrong in my code?
The problem is that you're using a single coordinates array. You keep setting and re-setting the values in that same array, and you keep storing that same array in new elements of coord_set. To fix this, you just need to use a new coordinates array on each pass through the outer loop:
for(var j=0;j<obj.length;j++)
{
coordinates = []; // <----- add this
for (var i=0;i<obj[j].length;i++)
I'm gonna assume that JSON.parse actually works... but since you said you are using jquery, i would use http://api.jquery.com/jQuery.parseJSON/ personally...
Few things about your code:
you never create a new object for coordinates, which is, by default, a global variable in JS. You must type:
var coordinates = []; // before the for (var i = 0; ...
where is this property "how_many" coming from? I don't see it in your first block of code... The code in your i loop should be:
coordinates[i] = obj[j][i];
finally, why do you need a copy of this transient object anyway? That should just do it:
coord_set[j] = { fillColor : 'rgba(255, 234, 111 ,0.5)', data : obj[j] };
// if you change your result set to give a code like that:
obj[0]= [ 125, 343, 456, 453 ] // and not: obj[0]={125, 343, 456, 453}