Parsing Html Page with Dart - html

I m trying to parse the following entry in an HTTP get request.
In the body, you see a script tag with a function call where I need to have access to the JSON inside the HTML tag.
<!DOCTYPE html>
<html translate="no">
<head></head>
<body>
<script>
$(function() {
intranet.list.frontend.init({
gridDataAndConfiguration: {
"Here is a big Json - WANTED"
},
},
});
</script>
</body>
</html>
Up to now, I don't parse the HTML with any Dart specific parsing method like
"parse" from package:html/parser.dart. That attempt was successful in searching for all the "script" tags inside the HTML DOM, but unfortunately, I did not find or showed the JSON or function call inside the referred script Tag!
The question is, how to access the JSON in the given HTML Page using Dart?
Solution :
RegExp re = RegExp(r'\[\{.*?\}\]');
var parsedHtml = parse(htmlText);
var allScripts = parsedHtml.getElementsByTagName('script');
for (int i = 0; i < allScripts.length; i++) {
if (allScripts[i].innerHtml.contains(startString)) {
Iterable<String> result =
re.allMatches(allScripts[i].innerHtml).map((m) => m[0]);
List<dynamic> jsonParsed = [];
for (var match in result) jsonParsed.add(jsonDecode(match));
Thanks for your answer & help.

Related

Parse multi level JSON from URL

All.
I found this script which is rather promising for what I am trying to do.
It works great with the hardcoded XML script.
However, I need to parse the file itself from an external URL.
Thank You.
Contents of the example file.
{"icestats":{"admin":"admin","host":"192.168.2.203","location":"Radio","server_id":"Icecast 2.4.4","server_start":"Mon, 24 May 2021 16:54:10 +0000","server_start_iso8601":"2021-05-24T16:54:10+0000","source":{"audio_info":"channels=2;samplerate=44100;bitrate=256","channels":2,"genre":"various","listener_peak":3,"listeners":2,"listenurl":"http://192.168.2.203:8000/RadioOne","samplerate":44100,"server_description":"Unspecified description","server_name":"RadioOne","server_type":"audio/mpeg","stream_start":"Mon, 24 May 2021 21:59:34 +0000","stream_start_iso8601":"2021-05-24T21:59:34+0000","title":"KISS - Hide Your Heart","dummy":null}}}
Example of the linked file. (This is an example of the URL file, in the real-world URL, it will be my domain name, with the file attached to it. This file cannot be removed from the location it is at, it is sitting on another server in the network.)
http://192.168.2.203:8000/status-json.xsl
Full script (This will run and show the hardcoded XML tree without any modifications to the file)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Parse Nested JSON Data in JavaScript</title>
</head>
<body>
<script>
/* Storing multi-line JSON string in a JS variable
using the new ES6 template literals */
var json = '{"icestats":{"admin":"admin","host":"192.168.2.203","location":"Radio","server_id":"Icecast 2.4.4","server_start":"Mon, 24 May 2021 16:54:10 +0000","server_start_iso8601":"2021-05-24T16:54:10+0000","source":{"audio_info":"channels=2;samplerate=44100;bitrate=256","channels":2,"genre":"various","listener_peak":3,"listeners":2,"listenurl":"http://192.168.2.203:8000/RadioOne","samplerate":44100,"server_description":"Unspecified description","server_name":"RadioOne","server_type":"audio/mpeg","stream_start":"Mon, 24 May 2021 21:59:34 +0000","stream_start_iso8601":"2021-05-24T21:59:34+0000","title":"KISS - Hide Your Heart","dummy":null}}}';
// This is the link to the file; the file contents are what is above.
//var json = "http://192.168.2.203:8000/status-json.xsl";
// Converting JSON object to JS object
var obj = JSON.parse(json);
// Define recursive function to print nested values
function printValues(obj) {
for(var k in obj) {
if(obj[k] instanceof Object) {
printValues(obj[k]);
} else {
document.write(obj[k] + "<br>");
};
}
};
printValues(obj);
document.write("<hr>");
document.write(obj["icestats"]["source"]["title"]);
</script>
</body>
</html>
When I run the script with the URL link only, I get the following error.
Uncaught SyntaxError: Unexpected token h in JSON at position 0
at JSON.parse (<anonymous>)
at music2.asp:18
Which points to this line.
var obj = JSON.parse(json);
This code was provided for me and it works great.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Zvonko *</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
</head>
<body>
<script>
// fetch the JSON data from your URL:
jQuery.get( "http://localhost:8000/status-json.xsl" , showData, "json" );
function showData(data){
// no need to Converting JSON string to JS object
// jQuery converted it for you
//var obj = JSON.parse(data);
printValues(data);
document.write("_______________________________");
if(data["icestats"] && data["icestats"]["source"]){
document.write(data["icestats"]["source"]["title"]);
// This next line, I use to pass a variable to an input field to submit to the database.
$(".myid").val(data["icestats"]["source"]["title"]);
}
// Converting your JSON string from top to JS object
var jsonobj = JSON.parse(yourJson);
printValues(jsonobj);
document.write("_______________________________");
if(jsonobj["icestats"] && data["icestats"]["source"]){
document.write(jsonobj["icestats"]["source"]["title"]);
}
}
// Define recursive function to print nested values
function printValues(obj) {
for(var k in obj) {
if(obj[k] instanceof Object) {
printValues(obj[k]);
} else {
document.write(k + ": " + obj[k]);
};
}
};
</script>
</body>
</html>
<form action="Send.asp" method="post">
<input type="text" name="Title" class="myid" style="border:1px double #000;">
<input type="submit" name="Submit">
</form>
Thanks to, Zvonko, for the code, on another side.
This one is completed.

How to get clean json from wikipedia API

I want to get the result from a wikipedia page https://en.wikipedia.org/wiki/February_2 as JSON.
I tried using their API: https://en.wikipedia.org/w/api.php?action=parse&page=February_19&prop=text&formatversion=2&format=json
Though it is giving it as Json format. The content is HTML. I want only the content.
I need a way to get clean result.
If you want plain text without markup, you have first to parse the JSON object and then extract the text from the HTML code:
function htmlToText(html) {
let tempDiv = document.createElement("div");
tempDiv.innerHTML = html;
return tempDiv.textContent || tempDiv.innerText || "";
}
const url = 'https://en.wikipedia.org/w/api.php?action=parse&page=February_19&prop=text&format=json&formatversion=2&origin=*';
$.getJSON(url, function(data) {
const html = data['parse']['text'];
const plainText = htmlToText(html);
const array = [...plainText.matchAll(/^\d{4} *–.*/gm)].map(x=>x[0]);
console.log(array);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Update: I edited the code above according to the comment below. Now the function extracts all the list items putting them into an array.
I guess by clean you mean the source wikitext. In that case you can use the revisions module:
https://en.wikipedia.org/w/api.php?action=query&titles=February_2&prop=revisions&rvprop=content&formatversion=2&format=json
See API:Get the contents of a page and API:Revisions for more info.

How to only send HTTP response as plain text (HTML) [duplicate]

This question already has answers here:
What is the difference between client-side and server-side programming?
(3 answers)
Closed 2 years ago.
I need to implement a calculator on my webpage, which will receive some arguments in the url and is supposed to return just the result, nothing else.
Example:
http://example.com/calc/?x=244&y=123&op=plus
I wrote a program using HTML and JavaScript which returns the correct result and prints it on the webpage.
This prints the result.
But the client doesn't just receive the result, but the whole html & script. Does anyone know how I can send only the result to the client?
Edit: If this cannot be done with HTMP and JS, how else?
<!DOCTYPE html>
<html>
<body>
<p id="demo"></p>
<script>
function calculate(url) {
// ...
}
let url = window.location.href;
document.write(parseInt(calculate(url)));
</script>
</body>
</html>
Desired result: 367 is returned to the HTTP client
Actual result: < !DOCTYPE html> .... ...... is returned to the HTTP client
Try the following
<!DOCTYPE html>
<html>
<body>
<p id="demo"></p>
<script>
function calculate (url_string) {
try {
var url = new URL(url_string);
var x = parseInt(url.searchParams.get("x"));
var y = parseInt(url.searchParams.get("y"));
switch(url.searchParams.get("op")){
case "plus": return x + y;
// add more cases here
}
} catch(e){}
}
let url = window.location.href;
document.write(parseInt(calculate(url)));
</script>
</body>
</html>

How to syntax highlight JSON inside a HTML page on the client side?

I am using a HTML documentation page by an external service which renders JSON snippets within an HTML page.
The HTML source code looks like this:
<pre>{
"product-link": "https://example.com/product-link",
"teaser_image": "https://example.com/teaser-image",
"product_image_first": "https://example.com/product-image-first",
"headline": "Example headline",
}</pre>
The JSON block renders without syntax highlighting.
Since I am not in control of the external service I would like to apply syntax highlighting (color) to the JSON snippet via user script.
I found Greasemonkey but still missing the point on how to inject a syntax highlighter library.
Thanks to xander here is the first working version of my user script base on code-prettify:
(function(d) {
stylizePreElements = function() {
var preElements = document.getElementsByTagName("pre");
for (i = 0; i < preElements.length; ++i) {
var preElement = preElements[i];
preElement.className += "prettyprint";
}
};
injectPrettifyScript = function() {
var scriptElement = document.createElement('script');
scriptElement.setAttribute("src", "https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js");
document.head.appendChild(scriptElement);
};
stylizePreElements();
injectPrettifyScript();
})(document)
Thank you for making my day nicer!

Mustache.js iterate over all arrays

I'm still busy trying to setup a JSON file to a HTML website. So if the json changes the changes are dynamically loaded in the HTML. Till this far i'm able to retreive the content and even request some content. But not everything that i want because the markup from the JSON is a bit weird.
Because of the cross-site protection I was not able to do a JSOP request directly, so i solved that with a little trick i saw somewhere. I've created a test.php that simply does:
That way I circumvent the cross-site protection, and everything works well. Only problem is that I can't iterate over all the arrays that i want. Currently i'm using the following script to do a JSOP call and get the data. And the output is a nice description between the <li></li>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
</head>
<body>
<ul id="episodes">
</ul>
<script src="http://cdnjs.cloudflare.com/ajax/libs/mustache.js/0.7.0/mustache.min.js"></script>
<script src="http://ps3scenefiles.com/json/handlebars.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script id="episodes-template" type="text/template">
<li>{{description}}</li>
</script>
<script>
$(function() {
$.getJSON('http://ps3scenefiles.com/json/test.php', function(data) {
var template = $('#episodes-template').html();
var info = Mustache.to_html(template, data);
$('#episodes').html(info);
});
});
</script>
</body>
</html>
But when you open the link to the JSON (http://ps3scenefiles.com/json/test.php), you see that the Episodes array has another array with just numbers. How can i create a list like
Episode: 1
Id:13605 Active:true Lang:en Link: url
Id:16525 Active:true Lang:ru Link: url
Episode: 2
Id:14854 Active:true Lang:en Link: url
Id:19445 Active:true Lang:ru Link: url
So to be clear, how can i do a mustache (or handlebars) templating to make it look like the example?
You can use Handlebars helper as mentioned in this answer
Here is a fiddle without styling, that prints out the data you expect (sort of, not all fields).
Here is the helper function -
Handlebars.registerHelper('eachkeys', function(context, options) {
var fn = options.fn, inverse = options.inverse;
var ret = "";
var empty = true;
for (key in context) { empty = false; break; }
if (!empty) {
for (key in context) {
ret = ret + fn({ 'key': key, 'value': context[key]});
}
} else {
ret = inverse(this);
}
return ret;
});