wikimedia api getting relavant data from json string - javascript

This is the question I asked yesterday. I was able to get the required data. The final data is like this. Please follow this link.
I tried with the following code to get all the infobox data
content = content.split("}}\n");
for(k in content)
{
if(content[k].search("Infobox")==2)
{
var infobox = content[k];
alert(infobox);
infobox = infobox.replace("{{","");
alert(infobox);
infobox = infobox.split("\n|");
//alert(infobox[0]);
var infohtml="";
for(l in infobox)
{
if(infobox[l].search("=")>0)
{
var line = infobox[l].split("=");
infohtml = infohtml+"<tr><td>"+line[0]+"</td><td>"+line[1]+"</td></tr>";
}
}
infohtml="<table>"+infohtml+"</table>";
$('#con').html(infohtml);
break;
}
}
I initially thought each element is enclosed in {{ }}. So I wrote this code. But what I see is, I was not able to get the entire infobox data with this. There is this element
{{Sfn|National Informatics Centre|2005}}
occuring which ends my infobox data.
It seems to be far simpler without using json. Please help me

Have you tried DBpedia? Afaik they provide template usage information. There is also a toolserver tool named Templatetiger, which does template extraction from the static dumps (not live).
However, I once wrote a tiny snippet to extract templates from wikitext in javascript:
var title; // of the template
var wikitext; // of the page
var templateRegexp = new RegExp("{{\\s*"+(title.indexOf(":")>-1?"(?:Vorlage:|Template:)?"+title:title)+"([^[\\]{}]*(?:{{[^{}]*}}|\\[?\\[[^[\\]]*\\]?\\])?[^[\\]{}]*)+}}", "g");
var paramRegexp = /\s*\|[^{}|]*?((?:{{[^{}]*}}|\[?\[[^[\]]*\]?\])?[^[\]{}|]*)*/g;
wikitext.replace(templateRegexp, function(template){
// logabout(template, "input ");
var parameters = template.match(paramRegexp);
if (!parameters) {
console.log(page.title + " ohne Parameter:\n" + template);
parameters = [];
}
var unnamed = 1;
var p = parameters.reduce(function(map, line) {
line = line.replace(/^\s*\|/,"");
var i = line.indexOf("=");
map[line.substr(0,i).trim() || unnamed++] = line.substr(i+1).trim();
return map;
}, {});
// you have an object "p" in here containing the template parameters
});
It features one-level nested templates, but still is very error-prone. Parsing wikitext with regexp is as evil as trying to do it on html :-)
It may be easier to query the parse-tree from the api: api.php?action=query&prop=revisions&rvprop=content&rvgeneratexml=1&titles=....
From that parsetree you will be able to extract the templates easily.

Related

How can I create a syntax like vue js in vanilla JavaScript?

<div id="">
<span>{{msg}}</span>
</div>
Let's think msg is variable of JavaScript and now I want to get the parent tag of {{msg}} and push a new value by innerHTML, here {{msg}} working as an identity.
demo JavaScript example:
<script>
var msg = "This is update data";
{{msg}}.parentElement.innerHTML=msg;
</scritp>
This is not actual JavaScript code, only for better understanding.
You can use jquery easily to find that element and then replace the text
var msg = "This is update data";
$(`span:contains(${msg})`).html("Its New");
In javascript:
var spanTags = document.getElementsByTagName("span");
var msg = "This is update data";
var found;
for (var i = 0; i < spanTags.length; i++) {
if (spanTags[i].textContent == msg) {
found = spanTags[i];
break;
}
}
Now, you have found that element in found and you can now change its text
if (found) {
found.innerHTML = "New text";
}
The simplest approach is to treat the entire document as a string and then re-parse it when you're done.
The .innerHTML property is both an HTML decompiler and compiler depending on weather you're reading or writing to it. So for example if you have a list of variables that you want to replace in your document you can do:
let vars = {
msg: msg, // pass value as variable
test_number: 10, // pass value as number
test_str: 'hello' // pass value as string
};
let htmlText = document.body.innerHTML;
// find each var (assuming the syntax is {{var_name}})
// and replace with its value:
for (let var in vars) {
let pattern = '\\{\\{\\s*' + var + '\\s*\\}\\}';
let regexp = new RegExp(pattern, 'g'); // 'g' to replace all
htmlText = htmlText.replace(regexp, vars[var]);
}
// Now re-parse the html text and redraw the entire page
document.body.innerHTML = htmlText;
This is a quick, simple but brutal way to implement the {{var}} syntax. As long as you've correctly specified/designed the syntax to make it impossible to appear in the middle of html tags (for example <span {{ msg > hello </ }} span>) then this should be OK.
There may be performance penalties redrawing the entire page but if you're not doing this all the time (animation) then you would generally not notice it. In any case, if you are worried about performance always benchmark your code.
A more subtle way to do this is to only operate on text nodes so we don't accidentally mess up real html tags. The key to doing this is to write your own recursive descent parser. All nodes have a .childNodes attribute and the DOM is strictly a tree (non-cyclic) so we can scan the entire DOM and search for the syntax.
I'm not going to write complete code for this because it can get quite involved but the basic idea is as follows:
const TEXT_NODE = 3;
let vars = {
msg: msg, // pass value as variable
test_number: 10, // pass value as number
test_str: 'hello' // pass value as string
};
function walkAndReplace (node) {
if (node.nodeType === TEXT_NODE) {
let text = node.nodeValue;
// Do what you need to do with text here.
// You can copy the RegExp logic from the example above
// for simple text replacement. If you need to generate
// new DOM elements such as a <span> or <a> then remove
// this node from its .parentNode, generate the necessary
// objects then add them back to the .parentNode
}
else {
if (node.childNodes.length) {
for (let i=0; i<node.childNodes.length; i++) {
walkAndReplace(node.childNodes[i]); // recurse
}
}
}
}
walkAndReplace(document.body);

require() not working with variable - react native

I meet a weird problem. If I set a variable direclty with a value like this "const myString = 'someWord';" that work but if I take the value from a variable like this "const myString = someVariable;", that doesn't work, and if I set the value on a conditional block that doesn't work too.
So, work:
var jsonName = 'tramwayen';
const pathex = require('../assets/JSON/' + jsonName);
var json = JSON.parse(JSON.stringify(pathex));
doesn't work:
var jsonName = variable;
const pathex = require('../assets/JSON/' + jsonName);
var json = JSON.parse(JSON.stringify(pathex));
doesn't work:
var jsonName = '';
if (condition) {
jsonName = 'tramwayen';
}
const pathex = require('../assets/JSON/' + jsonName);
var json = JSON.parse(JSON.stringify(pathex));
I really don't understand.
I have this error :
"Invalid call at line 41: require('../assets/JSON/' + jsonName2)"
Most JS bundlers cannot handle dynamic require imports. You might want to load all of the files, and put them in an object:
let data = {
tramwayen: require('../assets/JSON/tramwayen.json'),
something: require('../assets/JSON/something.json'),
// and so on
};
And use the data object to retrieve the data you need.
From what I read while doing some research, it seems impossible to made a require dynamically. In react native require should be static.
But there are some solutions to avoid this issue.
Here is mine, I put all data of my differents Json on one single json, and I dynamically choice wich part of the data I want to get.
I can also, put all the static require on an object, and choose dynamicaly wich require I want to get.
solution 1:
const id = window.currentPI;
const json = require('../assets/JSON/mainData.json');
const nbreOfPix = json[`${id}`].preData.numberOfPictures;
solution 2:
const IMAGES = {
tramwayen: require('../assets/CtrlPI/PHOTO_articles/008_02_Img.png'),
tramwayen2: require('../assets/CtrlPI/PHOTO_articles/HC002_04_Img.png')
};
getImage = (name) => {
return IMAGES[name];
};

Parsing Javascript withing Html using HTML DOM PARSER

currently trying to parse the download link for zippyshare files in php the issue is I need to get their javascript and I am not being able to do it. This is the part of the page I need to parse:
<script type="text/javascript">
var somdfunction = function() {
var a = 327030;
document.getElementById('dlbutton').omg = 327033%78956;
var b = parseInt(document.getElementById('dlbutton').omg) * (327033%3);
var e = function() {if (false) {return a+b+c} else {return (a+3)%b + 3}};
document.getElementById('dlbutton').href = "/d/91667079/"+(b+18)+"/Animals%20%28Radio%20Edit%29-www.manomuzika.net.mp3";
if (document.getElementById('fimage')) {
document.getElementById('fimage').href = "/i/91667079/"+(b+18)+"/Animals%20%28Radio%20Edit%29-www.manomuzika.net.mp3";
}
var result = 0;
}
</script>
Which being fetched from its website using:
$html = file_get_html($url);
Basically they create the download links dynamically using javascript, I am able to get the source using my parser but I need to cut it down to getting the values of:
var a = 327030;
document.getElementById('dlbutton').omg = 327033%78956;
and finally
document.getElementById('dlbutton').href = "/d/91667079/"+(b+18)+"/Animals%20%28Radio%20Edit%29-www.manomuzika.net.mp3";
Once I am able to get these three variables from within the source I will be able to create the download link my issue at the moment is cutting it down to that.
I am using this parser:
http://simplehtmldom.sourceforge.net/
If you would like to see the source code I am able to parse at the moment here it is:
http://www.somf.us/music/test.php?url=http://www66.zippyshare.com/v/91667079/file.html
You need to use regex because simple is not a javascript parser.
Here's a hint to get you started:
preg_match('/var a = (\d+);/', file_get_contents($url), $m);
echo $m[1];

JSON stringify works when previewing from Dreamweaver but not from .AIR file when application created

I've been developing a simple application using Adobe AIR, the HTML and javascript version.
The application submits a form to an online URL.
The values of the forms are JSON strings.
I'm using this function to submit the data:
function fetchStudents()
{
var stmt = new air.SQLStatement();
stmt.sqlConnection = conn;
stmt.text = "SELECT * FROM studentsTable2 WHERE deleted='0'";
stmt.addEventListener(air.SQLEvent.RESULT, function(event){
var result = event.target.getResult();
sync_students = JSON.stringify(result.data);
fetchCourses();
});
stmt.addEventListener(air.SQLErrorEvent.ERROR, errorHandler);
stmt.execute();
}
JSON.stringify works when I test the application in DREAMWEAVER by using: preview in ADOBE AIR.
sync_students is then a JSON string filled with all the data from the table correctly formatted.
But when I have created the AIR file and installed the application and run it, it no longer works.
sync_students is then a JSON string but it is completely empty... [{},{},{}]
I have read around a lot and seen suggestions to use JSON2.js etc and I have tried these but I haven't been successful.
This is driving me crazy, any help would be greatly appreciated.
Thanks so much in advance!
Have a look at the accepted answer of this question. The problem here was that garbage collection reclaims some var 'too soon' : in other words, the scope is baaad. :
AIR Sqlite: SQLEvent.RESULT not firing, but statement IS executing properly
EDIT : All this is a question of scope. You should look into 'javascript scope' and 'javascript closure' keywords to have a better understanding of this (if i may suggest).
below just a (very) short summary about ONE WAY to define a 'class' in javascript :
var MyNameSpace = {};
var MyNameSpace.SchoolDataSource = function() {
this.publicMember = 2;
this.publicFunction = function(x) {
var newValue = this.publicMember + _privateMemberOne + x;
return _privateFunctionMul2(newValue);
} ;
var _privateMemberOne = 1;
var _privateFunctionMul2 = function (y) { return 2*y; } ;
};
var mySchoolDataSource = new MyNameSpace.SchoolDataSource();
mySchoolDataSource.publicFunction(3); // ok. (returns (3+2+1) * 2 = 12)
var bar = mySchoolDataSource.publicMember; // ok. ( === 2)
mySchoolDataSource._privateFunctionMul2(4); does not work, which is what we want.
var foo= mySchoolDataSource._privateMemberOne; // does not work, which is what we want.

Get Query String with Dojo

Users will be hitting up against a URL that contains a query string called inquirytype. For a number of reasons, I need to read in this query string with javascript (Dojo) and save its value to a variable. I've done a fair amount of research trying to find how to do this, and I've discovered a few possibilities, but none of them seem to actually read in a query string that isn't hard-coded somewhere in the script.
You can access parameters from the url using location.search without Dojo Can a javascript attribute value be determined by a manual url parameter?
function getUrlParams() {
var paramMap = {};
if (location.search.length == 0) {
return paramMap;
}
var parts = location.search.substring(1).split("&");
for (var i = 0; i < parts.length; i ++) {
var component = parts[i].split("=");
paramMap [decodeURIComponent(component[0])] = decodeURIComponent(component[1]);
}
return paramMap;
}
Then you could do the following to extract id from the url /hello.php?id=5&name=value
var params = getUrlParams();
var id = params['id']; // or params.id
Dojo provides http://dojotoolkit.org/reference-guide/dojo/queryToObject.html which is a bit smarter than my simple implementation and creates arrays out of duplicated keys.
var uri = "http://some.server.org/somecontext/?foo=bar&foo=bar2&bit=byte";
var query = uri.substring(uri.indexOf("?") + 1, uri.length);
var queryObject = dojo.queryToObject(query);
//The structure of queryObject will be:
// {
// foo: ["bar", "bar2],
// bit: "byte"
// }
In new dojo it's accessed with io-query:
require([
"dojo/io-query",
], function (ioQuery) {
GET = ioQuery.queryToObject(decodeURIComponent(dojo.doc.location.search.slice(1)));
console.log(GET.id);
});
Since dojo 0.9, there is a better option, queryToObject.
dojo.queryToObject(query)
See this similar question with what I think is a cleaner answer.

Categories