I'm making a script using node.js and i need to parse a script inside a website, exactly i need 2 part not only the entire script. The 2 parts are "stock" and "local" and their values.
<script id="z-vegas-pdp-props" type="application/json">
![CDATA[{
"layout": "cover",
"model": {
"layout": "cover",
"priceInfo": {
"showPriceHint": false,
"priceHintType": ""
},
"mediaInfo": {
"currentIndex": 0
},
"price": {
"currency": "EUR",
"value": 129.99,
"formatted": "129,99 €"
},
"originalPrice": {
"currency": "EUR",
"value": 129.99,
"formatted": "129,99 €"
},
"available": false,
"stock": 0
}
//here the scripts continues but i "trimmed it to make it more easy"
</script>
This is what i made but it's parsing all the code and not only the parts that i need.
let root = HTMLParser.parse(response.body);
let availabiltyDiv = root.querySelector("#z-vegas-pdp-props")
console.log(availabiltyDiv)
The data you're looking for is hiding in json format inside the CDATA in the script. So you first need to extract the json string, parse it and get to the target data. Incidentally, the json string sample in your question is malformed, but is presumably well formed in the actual script. Also, there is no local in your sample, so I'll use another value instead.
All in all:
const jstring = availabiltyDiv.childNodes[0].nodeValue.split('CDATA[')[1].split(']')[0]
const target = JSON.parse(jstring);
#to get to (for example) price and stock:
const price = target.model.price.formatted;
const stock = target.model.stock;
console.log(price,stock)
Output:
"129,99 €" 0
EDIT:
As expalined in the respoinse to your comment, I don't have access to your actual availabilityDiv but you can also try replacing
const jstring = availabiltyDiv.childNodes[0].nodeValue.split('CDATA[')[1].split(']')[0]
with
const jstring = availabiltyDiv.innerHTML.split('CDATA[')[1].split(']')[0]
or with
const jstring = availabiltyDiv.innerText.split('CDATA[')[1].split(']')[0]
and see if they work.
Related
I'm looking for a library to convert a text file to JSON.
Do you know which one has the following behavior?
I already test some libraries but without success.
The source files contains a list of key=value pairs, one key per line.
Converting to correct data type is important, my files has:
string keys
number keys
boolean keys
object (JSON) keys
arrays (of simple strings or of JSON objects)
Example
name = "test"
version = 3
enabled = true
fruit = {"type":"orange","color":"orange"}
consumers = ["kids", "adults"]
years = [2014, 2015]
fruits = [{"type":"orange","color":"orange"},{"type":"apples","method":"red"}]
Expected Result after conversion: Valid JSON (don't need style/identation)
{
"name": "test",
"version": 3,
"enabled": true,
"fruit": {
"type": "orange",
"color": "orange"
},
"consumers": [
"kids",
"adults"
],
"years": [
2014,
2015
],
"fruits": [
{
"type": "orange",
"color": "orange"
},
{
"type": "apples",
"method": "red"
}
]
}
The format you're using isn't standardized so I'm doubtful you'll find a package that can parse it out of the box. Your values do look to be valid JSON primitives so you can leverage JSON.parse to parse the right hand side. With that you'd just need a parser to robustly pull out all the raw [key, value] pairs, but most parsers probably try to do more than just that which might not be what you want.
If you know the input will always be clean and don't need a completely robust parser, it's not difficult to roll this yourself:
const data = fs.readFileSync('./data.txt', {encoding: 'utf8'}).split('\n').filter(Boolean)
const obj = {}
for (const line of data) {
const [key, val] = line.split(/\s*=\s*(.+)/)
obj[key] = JSON.parse(val)
}
I need to write REST API in Node jS for JSON to JSON transfromation.
There are many library and I sort listed "JSONata"
Please find JSONata simple sample here
The challenge is API receive JSON which has data and map but JSONata require map value without quotes.
{
"data" : {
"title" : "title1",
"description": "description1",
"blog": "This is a blog.",
"date": "11/4/2013"
},
"map" : {
"name": "title",
"info": "description",
"data" : {
"text": "blog",
"date": "date"
}
}
}
but the map object expected by JSONata is like below.
{
"name": title,
"info": description,
"some" : {
"text": blog,
"date": date
}
}
The above JSON key is in Quotes and value without Quotes.
Please find the NodeJS API code.
app.post('/JSONTransform', function(req, res, next)
{
const data = req.body.data;
const map = req.body.map;
var expression = jsonata(map);
var result = expression.evaluate(data);
res.send(result);
});
I can write simple function to remove quotes but the above map is simple example. It can be any no of child object and may have some special character in the value including quotes.
I prefer some npm library or standard way to remove quotes or configure JSONata to accepts quotes in value.
Appreciate if you suggest any other library or option.
This Node JS API is called from ASP.NET Core Web API.
ASP.NET Core Web API gets the data and map from database and pass this as single JSON to Node JS API.
Please suggestion solution to this problem or best alternative.
Thanks
Raj
I found solution to this problem.
Pass the single JSON that has both data and map. Since MAP is not valid JSON, I made entire map as string and escaped doubles quotes which is inside the string.
Please find the sample.
{
"map": "{ \"name\": title, \"info\": description, \"data\": { \"text\": blog, \"date\": date }}",
"data": {
"title": "title1",
"description": "description1",
"blog": "This is a blog.",
"date": "11/4/2013"
}
}
In Jmeter JSR223Preprocessor with Groovy I load a generic JSON file xyz looking like this:
{
"name": "dummy",
"block1": {
"var1": 1,
"var2": {
"value": 1,
"unit": "Miles",
},
"var3": {
"value": 3,
"unit": "Seconds",
},
"myList": [{"Id": 0}]
}
I like to come up with an elegant way to replace the var2 "Value" with a configurable value sayconfVal. This works:
String path = vars.get("basePath")+"xyz.json" ;
xyz = new File(path).getText("UTF-8");
xyz = xyz.replaceAll ('"value": 1', '"value": ${confVal}');
However I am not comfortable with this because it is vulnerable with spaces, and moreover I have another Value on var3 and someone could accidentally change 1 to 3. So I like to index to that child var2.Value then get Value.
Thank you
Add JSR223 PreProcessor as a child of the HTTP Request which body you need to amend
Put the following code into "Script" area:
def xyz = new File(vars.get("basePath")+"xyz.json")
def request = new groovy.json.JsonSlurper().parse(xyz)
request.block1.var2.value=vars.get('confVal') as int
xyz.newWriter().withWriter { writer ->
writer << new groovy.json.JsonBuilder(request).toPrettyString()
}
That's it, the value in the file should be replaced with what you have in the ${confVal} variable in the runtime.
More information:
Groovy: Parsing and producing JSON
Apache Groovy - Why and How You Should Use It
bool seems to work as expected, as does json type (postgres), but all of my id cols populate as strings (breaking the front-end code)
Is there a way to a. fix it, or b. tell bookshelf that that field is an integer?
Update
By request, here's some code snippets. I'm just testing the waters with node/bookshelf, so this isn't complicated code; it's mostly right out of the getting started guide. The database is an existing one we've been using for 2ish years, the id cols are definitely int for all tables
One good example, Calendars and
var Appointment = bs.Model.extend({
tableName: 'ec__appointments',
});
var Calendar = bs.Model.extend({
tableName: 'ec__calendars',
appointments: function() {
return this.hasMany(Appointment, 'calendar_id');
},
});
For this one, the calendar ids come down as int, but when I fetch({withRelated:['appointments']}), the appointment.id is a string.
{
"calendars": [
{
"id": 2,
"name": "Default Calendar",
"created_at": "2015-03-06T09:35:58.000Z",
"updated_at": "2016-03-23T03:28:07.000Z",
"appointments": [
{
"id": "107",
"calendar_id": "2",
"name": "Test",
"starts_at": null,
"ends_at": null,
"created_at": "2015-05-29T23:13:20.000Z",
"updated_at": "2015-05-29T23:13:20.000Z",
},
You can fix this problem with the following code:
var pg = require('pg');
pg.types.setTypeParser(20, 'text', parseInt);
More details here: https://github.com/tgriesser/knex/issues/387
I havee this Json format:
{
"AAPL": {
"cname": "Apple inc",
"symbol": "AAPL",
"logo": "apple.png",
"price": 0
},
"NVDA": {
"cname": "Nvidia Corporation",
"symbol": "NVDA",
"logo": "nvidia.png",
"price": 0
},
"GOOG": {
"cname": "Google inc",
"symbol": "GOOG",
"logo": "google.png",
"price": 0
}
}
I'd like to keep the same format while inserting to the mongoDB.
How can i do that using mongoDB native driver for node.js and using the mongo shell.
You have a single JSON object here. When you want each of its keys to be a separate document, you need to transform the object into an array first. While you do that, you also need to move the stock-symbol which is the key of each sub-object into the object itself so it doesn't get lost in the process. You can do this with a Javascript for-in loop:
jsonObject = ... // that JSON code you posted above
var docs = [];
for (var key in jsonObject) {
var doc = jsonObject[key];
doc.symbol = key;
docs.push(doc);
}
You can then pass the whole array to db.collection.insert to make a batch-insert of all documents in that array.