In Angular 8 I have to send an XML contents to the server.
I prefer converting it to JSON and then it send with:
this.http.post (${BASE_URL},body).subscribe
Is it a wise step ?
Generally: How can I read a file in client side and copy its contents into body ?
Thank you in advance
There are many tools and libraries for converting XML to JSON, and they all do it differently. All of them have different strengths and weaknesses; they differ in what kinds of XML they handle well. If the JSON that you want to generate has already been defined by a third party, then you're unlikely to find a tool that generates precisely the desired format. In such cases you're better off writing the conversion rules yourself in XSLT.
You have to install "xml2js" dependency.I hope it will helps you.
import { parseString } from "xml2js";
let xml = `<book><title>Some title</title>
<description>some description </description>
<author>
<id>1</id>
<name>some author name</name>
</author>
<review>nice book</review>
<review>this book sucks</review>
<review>amazing work</review></book>
`;
parseString(xml, function(err, result) {
console.dir(result);
});
}
jsonxml should what you're looking for.
function xml2json(xml, // element or document DOM node
tab) // tab or indent string for pretty output formatting
// omit or use empty string "" to supress.
// returns JSON string
Related
My SOR application is returning result set, I'm performing below binary-encode and decode to retrieve json
<xsl:variable name="response_json">
<xsl:copy-of select="dp:decode(dp:binary-encode($resp/result/binary/node()), 'base-64')"/>
</xsl:varibale>
response_json - {"code":"00", "description":"Success"}.
Now how do we parse through above response_json and assign "code"/"description" values to xsl:variables and context variables using XSLTs
You have two options, IMO one good and one bad...
Let's start with the bad one which you are already on as you are using XSLT for JSON data.
Even worse option is of course to use the JSON as text only and check for the value of code and description using XSLT String functions, otherwise you need to transform the JSON data into JSONx that can be handled in XSLT by using a convert of Query Params to XML.
To do this you need to pass your JSON to a new Action (Convert QP) and then into a new Transform.
You can then use DP's JSONx to handle any "JSON" data operations you'd like as XML in the XSLT stylesheet and when done call store://jsonx2json.xsl in a new Transform to transform it into "real" JSON.
I assume you are using a dp:url-open() as you get your response in a variable but if your service has Request/Resoonse as JSON the context VAR __JSONASJSONX will automatically hold a JSONx object for you that you can use as the INPUT to any XSLT Transform action.
That being said, let's move over to the good solution; use GWS!
GWS is added to DataPower to handle JSON (and anything other than XML) and you can call a GWS from your XSLT using dp:gatewayscript() as well. See this sample: https://github.com/ibm-datapower/datapower-samples/blob/master/gatewayscript/example-ext-func-dp-gwscript.xsl
If your Transform is not doing anything XML specific I'd rewrite it into GWS!
I am getting an XML with following structure
<?xml version="1.0" encoding="UTF-8"?>
<Data>
<datym>
<bla bla>
</datym>
<datym>
<bla bla>
</datym>
</Data>
This i can successfully parsed to json and do all the work. Sometimes i am getting an empty xml with following format.
<?xml version="1.0" encoding="UTF-8"?>
<Data></data>
This however fail to parse as an xml or json using logic apps.So how do i do a validation if this is parsable XML or the empty XML? i thought of using contains() function after initiate a string but this is huge performance hit.
Thanks for your ideas.
I thought your empty xml example is till parsable. I tried to parse a xml file to a json file. This is my xml content.
<Invoices
xmlns="http://gateway.com/schemas/Invoices"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://gateway..com/schemas/Invoices Invoices.xsd">
<DocumentInfo></DocumentInfo>
<Header></Header>
<Documents></Documents>
</Invoices>
After parse, this is the json content:
{
"Invoices": {
"#xmlns": "http://gateway.com/schemas/Invoices",
"#xmlns:xsi": "http://www.w3.org/2001/XMLSchema-instance",
"#xsi:schemaLocation":
"http://gateway..com/schemas/InvoicesInvoices.xsd",
"DocumentInfo": "",
"Header": "",
"Documents": ""
}
}
So maybe you could refer to my Logic App flow. I used a xml file as a display.
Hope this could help you, if you still have other questions, please let me know.
I actually find a way around this. So i thought i will answer my own so future others would find it useful.
My method is using XPATH.
Simply check the first node. If it returns empty array then its empty otherwise go with the normal processing.
xpath(xml(base64ToString(variables('content'))),'//datym')
or
xpath(xml(base64ToString(variables('content'))),'//datym[1]')
Currently I'm trying to differentiate between different serialized text formats. Mainly between XBRL, XML, CSV, and JSON.
I would like to assume that, checking by steps, if we use a parser to parse an XBRL/XML and returns without any exception thrown, then it's a valid XML document and needs further checking to see if the document is a regular xml or an xbrl.
If the first check fails, try parsing the csv. If parsing the csv returns an exception, try parsing as a JSON. If none of the above works, it's an invalid document.
Would this be an exceptional way of identifying the type of text format the document is? Or is there a better way? (i.e reading the first few bytes of the document etc...).
thanks
If you know the JSON will be an object or array, and that the content HAS to be one of those four...
if(content.charAt(0) == "[" || content.charAt(0) == "{") {
// JSON
} else if(content.charAt(0) == "<") {
if(content.indexOf("xmlns=\"http://www.xbrl.org/2001/instance\"") >= 0) {
// XBRL
} else {
// XML
}
} else {
// CSV ?...
// first remove strings
var testCSV = content.replace("\"\"", ""); // remove escaped quotes
testCSV = testCSV.replace(/".*?"/g, ""); // match-remove quoted strings
var lines = testCSV.split("\n");
if(lines.length === 1 && lines[0].split(",").length > 1) {
// only 1 row so we can only verify if there is two or more columns
// CSV
} else if(lines.length > 1 && lines[0].split(",").length > 1 && lines[0].split(",").length === lines[1].split(",").length) {
// we know there's multiple lines with the same number of columns
// CSV
}
// can't be sure what it is
// ???
}
The above will give you a reasonable amount of certainty.
EDIT I added a quick CSV test as well.
I would like to specifically address the difference between XML and XBRL.
XML is a syntax. An XML parser may be tasked with parsing out the elements, checking the elements against a schema, and perform other syntax-level validations against the structure of the document. For the most part, parsing XML is a syntax check against the structure of the document.
XBRL leverages the XML format, so all XBRL documents are also XML documents. However, the XBRL specification goes above and beyond an XML parser to ensure that the semantics of the data encoded in the XML format are correct. An XBRL parser, for example, loads a calculation linkbase, if one is defined, and ensures that the numeric values that participate in the calculation add up correctly as defined by the calculation linkbase. Tools such as Gepsio perform this XBRL-specific semantic check work to ensure that the data encoded in the XML format conforms to all of the rules defined in the XBRL Specification.
XBRL is semantic rules against XML-encoded data. Valid XBRL is also valid XML, but the reverse is not necessarily true.
XBRL has not been seen as a "language" by users any more. XBRL has became a semantic standard for financial business documents. Initially, XML was vastly adopted by companies because in that time JSON did not even exist (we are talking about 90's).
Today, XML is used just because its facility of creating a huge amount of linked data (through XLinks, Schemas and Linkbases). However, you are not stuck in XML format, you can use any one of this technology for representing the XBRL file: XML, JSON or CSV.
If you already have a XBRL-XML file, you can convert it to XBRL-JSON format through free and Open-source tools - e.g.: https://youtu.be/Xr6v4jL535w.
Part of a website's JSON response had this (... added for context):
{..., now:function(){return(new Date).getTime()}, ...}
Is adding anonymous functions to JSON valid? I would expect each time you access 'time' to return a different value.
No.
JSON is purely meant to be a data description language. As noted on http://www.json.org, it is a "lightweight data-interchange format." - not a programming language.
Per http://en.wikipedia.org/wiki/JSON, the "basic types" supported are:
Number (integer, real, or floating
point)
String (double-quoted Unicode
with backslash escaping)
Boolean
(true and false)
Array (an ordered
sequence of values, comma-separated
and enclosed in square brackets)
Object (collection of key:value
pairs, comma-separated and enclosed
in curly braces)
null
The problem is that JSON as a data definition language evolved out of JSON as a JavaScript Object Notation. Since Javascript supports eval on JSON, it is legitimate to put JSON code inside JSON (in that use-case). If you're using JSON to pass data remotely, then I would say it is bad practice to put methods in the JSON because you may not have modeled your client-server interaction well. And, further, when wishing to use JSON as a data description language I would say you could get yourself into trouble by embedding methods because some JSON parsers were written with only data description in mind and may not support method definitions in the structure.
Wikipedia JSON entry makes a good case for not including methods in JSON, citing security concerns:
Unless you absolutely trust the source of the text, and you have a need to parse and accept text that is not strictly JSON compliant, you should avoid eval() and use JSON.parse() or another JSON specific parser instead. A JSON parser will recognize only JSON text and will reject other text, which could contain malevolent JavaScript. In browsers that provide native JSON support, JSON parsers are also much faster than eval. It is expected that native JSON support will be included in the next ECMAScript standard.
Let's quote one of the spec's - https://www.rfc-editor.org/rfc/rfc7159#section-12
The The JavaScript Object Notation (JSON) Data Interchange Format Specification states:
JSON is a subset of JavaScript but excludes assignment and invocation.
Since JSON's syntax is borrowed from JavaScript, it is possible to
use that language's "eval()" function to parse JSON texts. This
generally constitutes an unacceptable security risk, since the text
could contain executable code along with data declarations. The same
consideration applies to the use of eval()-like functions in any
other programming language in which JSON texts conform to that
language's syntax.
So all answers which state, that functions are not part of the JSON standard are correct.
The official answer is: No, it is not valid to define functions in JSON results!
The answer could be yes, because "code is data" and "data is code".
Even if JSON is used as a language independent data serialization format, a tunneling of "code" through other types will work.
A JSON string might be used to pass a JS function to the client-side browser for execution.
[{"data":[["1","2"],["3","4"]],"aFunction":"function(){return \"foo bar\";}"}]
This leads to question's like: How to "https://stackoverflow.com/questions/939326/execute-javascript-code-stored-as-a-string".
Be prepared, to raise your "eval() is evil" flag and stick your "do not tunnel functions through JSON" flag next to it.
It is not standard as far as I know. A quick look at http://json.org/ confirms this.
Nope, definitely not.
If you use a decent JSON serializer, it won't let you serialize a function like that. It's a valid OBJECT, but not valid JSON. Whatever that website's intent, it's not sending valid JSON.
JSON explicitly excludes functions because it isn't meant to be a JavaScript-only data
structure (despite the JS in the name).
A short answer is NO...
JSON is a text format that is completely language independent but uses
conventions that are familiar to programmers of the C-family of
languages, including C, C++, C#, Java, JavaScript, Perl, Python, and
many others. These properties make JSON an ideal data-interchange
language.
Look at the reason why:
When exchanging data between a browser and a server, the data can only
be text.
JSON is text, and we can convert any JavaScript object into JSON, and
send JSON to the server.
We can also convert any JSON received from the server into JavaScript
objects.
This way we can work with the data as JavaScript objects, with no
complicated parsing and translations.
But wait...
There is still ways to store your function, it's widely not recommended to that, but still possible:
We said, you can save a string... how about converting your function to a string then?
const data = {func: '()=>"a FUNC"'};
Then you can stringify data using JSON.stringify(data) and then using JSON.parse to parse it (if this step needed)...
And eval to execute a string function (before doing that, just let you know using eval widely not recommended):
eval(data.func)(); //return "a FUNC"
Via using NodeJS (commonJS syntax) I was able to get this type of functionality working, I originally had just a JSON structure inside some external JS file, but I wanted that structure to be more of a Class, with methods that could be decided at run time.
The declaration of 'Executor' in myJSON is not required.
var myJSON = {
"Hello": "World",
"Executor": ""
}
module.exports = {
init: () => { return { ...myJSON, "Executor": (first, last) => { return first + last } } }
}
Function expressions in the JSON are completely possible, just do not forget to wrap it in double quotes. Here is an example taken from noSQL database design:
{
"_id": "_design/testdb",
"views": {
"byName": {
"map": "function(doc){if(doc.name){emit(doc.name,doc.code)}}"
}
}
}
although eval is not recommended, this works:
<!DOCTYPE html>
<html>
<body>
<h2>Convert a string written in JSON format, into a JavaScript function.</h2>
<p id="demo"></p>
<script>
function test(val){return val + " it's OK;}
var someVar = "yup";
var myObj = { "func": "test(someVar);" };
document.getElementById("demo").innerHTML = eval(myObj.func);
</script>
</body>
</html>
Leave the quotes off...
var a = {"b":function(){alert('hello world');} };
a.b();
Im just wondering if I am pushing JSON too far? and if anyone has hit this before?
I have a xml file:
<?xml version="1.0" encoding="UTF-8"?>
<customermodel:Customer xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:customermodel="http://customermodel" xmlns:personal="http://customermodel/personal" id="1" age="1" name="Joe">
<bankAccounts xsi:type="customermodel:BankAccount" accountNo="10" bankName="HSBC" testBoolean="true" testDate="2006-10-23" testDateTime="2006-10-23T22:15:01+08:00" testDecimal="20.2" testTime="22:15:01+08:00">
<count>0</count>
<bankAddressLine>HSBC</bankAddressLine>
<bankAddressLine>London</bankAddressLine>
<bankAddressLine>31 florence</bankAddressLine>
<bankAddressLine>Swindon</bankAddressLine>
</bankAccounts>
</customermodel:Customer>
Which contains elements and attributes....
Which when i convert to JSON gives me:
{"customermodel:Customer":{"id":"1","name":"Joe","age":"1","xmlns:xsi":"http://www.w3.org/2001/XMLSchema-instance","bankAccounts":{"testDate":"2006-10-23","testDecimal":"20.2","count":"0","testDateTime":"2006-10-23T22:15:01+08:00","bankAddressLine":["HSBC","London","31 florence","Swindon"],"testBoolean":"true","bankName":"HSBC","accountNo":"10","xsi:type":"customermodel:BankAccount","testTime":"22:15:01+08:00"},"xmlns:personal":"http://customermodel/personal","xmlns:customermodel":"http://customermodel"}}
So then i send this too the client.. which coverts to a js object (or whatever) edits some values (the elements) and then sends it back to the server.
So i get the JSON string, and convert this back into XML:
<customermodel:Customer>
<id>1</id>
<age>1</age>
<name>Joe</name>
<xmlns:xsi>http://www.w3.org/2001/XMLSchema-instance</xmlns:xsi>
<bankAccounts>
<testDate>2006-10-23</testDate>
<testDecimal>20.2</testDecimal>
<testDateTime>2006-10-23T22:15:01+08:00</testDateTime>
<count>0</count>
<bankAddressLine>HSBC</bankAddressLine>
<bankAddressLine>London</bankAddressLine>
<bankAddressLine>31 florence</bankAddressLine>
<bankAddressLine>Swindon</bankAddressLine>
<accountNo>10</accountNo>
<bankName>HSBC</bankName>
<testBoolean>true</testBoolean>
<xsi:type>customermodel:BankAccount</xsi:type>
<testTime>22:15:01+08:00</testTime>
</bankAccounts>
<xmlns:personal>http://customermodel/personal</xmlns:personal>
<xmlns:customermodel>http://customermodel</xmlns:customermodel>
</customermodel:Customer>
And there is the problem, is doesn't seem to know the difference between elements/attributes so i can not check against a XSD to check this is now valid?
Is there a solution to this?
I cannot be the first to hit this problem?
JSON does not make sense as an XML encoding, no. If you want to be working with and manipulating XML, then work with and manipulate XML.
JSON is for when you need something that's lighter weight, easier to parse, and easier to write and read. It has a fairly simple structure, that is neither better nor worse than XML, just different. It has lists, associations, strings, and numbers, while XML has nested elements, attributes, and entities. While you could encode each one in the other precisely, you have to ask yourself why you're doing that; if you want JSON use JSON, and if you want XML use XML.
JsonML provides a well thought out standard mapping from XML<->JSON. If you use it, you'll get the benefit of ease-of-manipulation you're looking for on the client with no loss of fidelity in elements/attributes.
I wouldn't encode the xml schema information in the json string-- that seems a little backwards. If you're going to send them JSON, they shouldn't have any inkling that this is anything but JSON. The extra xml will serve to confuse and make the your interface look "leaky".
You might even consider just using xml and avoid the additional layer of abstraction. JSON makes the most sense when you know at least one party is actually using javascript. If this isn't the case it'll still work as well as any other transport format. But if you already have an xml representation it's a little excessive.
On the other hand, if your customer is really using javascript it will make it easier for them to use the data. The only concern is the return trip, and once it's in JSON who do you trust more to do the conversion back to xml correctly? You're probably better qualified for that, since it's your schema.
For this to work you would need to build additional logic/data into your serialize/unserialize methods - probably create something like "attributes" and "data" to hold the different parts:
{"customermodel:Customer":
{
"attributes": {"xmlns:xsi":"...", "xmlns:customermodel":"..."},
"data":
{
"bankAccounts":
{
"attributes": { ... }
"data" :
{
"count":0,
"bankAddressLine":"..."
}
}
}
}