Below is snippet of html that I will be parsing. It is stored inside a js variable.
<tr class='preview'>
<td class='statistics show' title='Show latest match stats'>
<button class="js-hide">Show</button>
</td>
<td class='match-details'>
<p>
<span class='team-home teams'>
<a href='#'>Leicester</a>
</span>
<span class='versus'>
<abbr title='Versus'> V </abbr>
</span>
<span class='team-away teams'>
<a href='#'>Crystal Palace</a>
</span>
</p>
</td>
<td class='kickoff'>
15:00
</td>
<td class='status'></td>
</tr>
<tr class='preview'>
<td class='statistics show' title='Show latest match stats'>
<button class="js-hide">Show</button>
</td>
<td class='match-details'>
<p>
<span class='team-home teams'>
<a href='#'>Liverpool</a>
</span>
<span class='versus'>
<abbr title='Versus'> V </abbr>
</span>
<span class='team-away teams'>
<a href='#'>Spurs</a>
</span>
</p>
</td>
<td class='kickoff'>
15:00
</td>
<td class='status'></td>
</tr>
Result ..
Leicester vs. Crystal Palace
Liverpool vs. Spurs
I'm interested in the home and away team names. The vs. can be added between each easily.
Could anyone suggest if there is a simple solution for parsing this string? Are RegEx the only approach?
What you're looking for is DOMParser with its parseFromString method.
Simply pass in your HTML string (and a specified mime-type like 'text/html') into the parser, and you'll get a Document object (or HTMLDocument, to be specific, if you specify the type as 'text/html').
With this Document, you can then query it as usual (whether with querySelector, getElement*, or a library like jQuery).
Here's an example:
var parsedHTML = new DOMParser().parseFromString(myHTMLVariable, 'text/html');
var teams = parsedHTML.querySelectorAll('.teams');
You can insert the HTML string into a temporary element and query it using DOM methods. For example
// HTML in "html" variable
var tmp = document.createElement('div');
tmp.innerHTML = html;
var homeTeams = tmp.querySelectorAll('.team-home');
Array.prototype.forEach.call(homeTeams, function(team) {
console.log(team.textContent);
});
Related
How to get text present in the second td.
<tr data-ng-repeat="s in systemSettings" class="ng-scope">
<td class="ng-binding">License Key</td>
<td class="ng-binding">rashmi123</td>
<td align="center">
<div data-ng-show="s.readOnly" class="text-warning ng-hide">read only</div>
<div data-ng-show="!s.readOnly"> <i class="glyphicon glyphicon-edit"></i> </div>
</td>
</tr>
I have tried to get it by using by
expect(element("tr:nth-child(2) td.ng-binding:nth-child(2)").getInnerHtml()).toBe("rashmi123");
but it is giving Invalid locator error.
Your element locator should contain the types like - xpath, css, etc...
expect(element(by.css("tr:nth-child(2) td.ng-binding:nth-child(2)")).getInnerHtml()).toBe("rashmi123");
Also you can use .getText() to get the text of an element instead of getInnerHtml.
var ele = element(by.css("tr:nth-child(2) td.ng-binding:nth-child(2)"));
expect(ele.getText()).toBe("rashmi123");
OR use the short form provided by protractor for element(by.css()) => $()
var ele = $("tr:nth-child(2) td.ng-binding:nth-child(2)");
expect(ele.getText()).toBe("rashmi123");
Hope it helps.
if my HTML is like this :
<tbody id="hasil-pencarian">
<tr>
<td align="center">1</td>
<td>TMS/IT/06/001</td>
<td>Erika Julia Widiyanti</td>
<td>Marketing</td>
<td>14-06-2015 13:59</td>
<td>14-06-2015 14:00</td>
<td>Erika test 1</td>
<td id="action" class="center" width="10px">
<a class="btn btn-success">
</td>
</tr>
</tbody>
I got all the html above like this :
var result = $("#hasil-pencarian").html();
But, How can I get all the HTML without the <td> with id='action' ?
Little confused. Any help will be so appreciated.
I think you could create clone then remove the element then get the content like
var result = $("#hasil-pencarian").clone().find('#action').remove().end().html();
First of all, I am asking this question is due to a broken API of petfinder. I am working on a rabbit rescue app (its web interface) and need some of petfinder's search results. Hopefully they fix the public API soon, but meanwhile I am using PHP to load their html content of search results and turn it into json for my front end to display.
The current method I use is to load the page into a invisible div tag and use jquery selector to map the content. But this is not efficient because it will also load up some of the original script and css files from petfinder. I would like to be able to manipulate the string directly.
Here are some of the examples:
Original code structure:
<html>
<head>
...
</head>
<body style="background:#ffffff">
<style type="text/css">
...
</style>
<body bgcolor="#FFFFFF" text="#000000" >
<table>
...
...
<tr class = "pfrow2">
<td><a href="//www.petfinder.com/petdetail/30773115" class="pflink" target="_blank">
Billie Bunny
</a>
</td>
<td>
Rabbit
</td>
<td>
Dutch
</td>
<td>
Adult
</td>
<td>
Small
</td>
<td class='legacy'>
<a href="//www.petfinder.com/petdetail/30773115" target="_blank">
<img src="//drpem3xzef3kf.cloudfront.net/photos/pets/30773115/1/?bust=1415669533&width=130" class="img pets" border="0">
</a>
</td>
</tr>
<tr class="pfrow1">
<td><a href="//www.petfinder.com/petdetail/30891970" class="pflink" target="_blank">
Barnabas Bunny
</a>
</td>
<td>
Rabbit
</td>
<td>
Himalayan, New Zealand
</td>
<td>
Young
</td>
<td>
Medium
</td>
<td class='legacy'>
<a href="//www.petfinder.com/petdetail/30891970" target="_blank">
<img src="//drpem3xzef3kf.cloudfront.net/photos/pets/30891970/3/?bust=1421966387&width=130" class="img pets" border="0">
</a>
</td>
</tr>
...
As you can see the information I really need is within tr class = "pfrow2" and tr class = "pfrow1". I wonder if there is a way I could do a similar grab $(".pfrow2").map(function(){}) if the class is actually within the string.
Alternatively, can I cut out the DOM before pfrow2 and after pfrow1?
BTW this is my current json output (note that I change width of the image because I want to use larger thumbnails).
[{
name: "Billie Bunny",
type: "Dutch",
age: "Adult",
size: "Small",
thumb: "//drpem3xzef3kf.cloudfront.net/photos/pets/30773115/1/?bust=1415669533&width=300",
link: "//www.petfinder.com/petdetail/30773115"
},{
name: "Barnabas Bunny",
type: "Himalayan, New Zealand",
age: "Young",
size: "Medium",
thumb: "//drpem3xzef3kf.cloudfront.net/photos/pets/30891970/3/?bust=1421966387&width=300",
link: "//www.petfinder.com/petdetail/30891970"
}]
I don't know how to make the string directly but I was able to cut the rows out for you. Assuming data is the result returned by your php.
var json = data.substring(data.indexOf('<tr class = "pfrow2">') - 21);
json = json.substring(0,json.lastIndexOf('</td>') + 5);
function widthChange() {
if (json.indexOf('&width=130') != -1) {
json = json.replace('&width=130','&width=300');
widthChange();
} else {
console.log(json);
// here you can inset json into your DOM
}
}
widthChange();
I have a javascript variable named response. This is the response from an ajax call. This variable has the following content:
<table id="ListCompanies" class="zebra-striped">
<thead>
<tr>
<th>Nom de la societe</th>
<th>Ville</th>
<th>Rue</th>
<th width="70"><a class="btn primary small createCompany" href="/PLATON/Admin/Company/Create">[+] Nouvelle societe</a> </th>
</tr>
</thead>
<tbody>
<tr id="13">
<td>INDUSTRIAL DEFENDER INC</td>
<td>FOXBOROUGH</td>
<td>Chestnut Street</td>
<td nowrap>
<a class="btn small editCompany" href="/PLATON/Admin/Company/Edit/13" id="13">Modifier</a>
<a class="btn small deleteCompany" href="/PLATON/Admin/Company/Delete/13" id="13">Supprimer</a>
</td>
</tr>
<tr id="14">
<td>INC CRANE NUCLEAR</td>
<td>GEORGIA KENNESAW</td>
<td>cobb International Blvd</td>
<td nowrap>
<a class="btn small editCompany" href="/PLATON/Admin/Company/Edit/14" id="14">Modifier</a>
<a class="btn small deleteCompany" href="/PLATON/Admin/Company/Delete/14" id="14">Supprimer</a>
</td>
</tr>
</tbody>
</table>
Load more
alert($("tbody", response).html()); gives me:
<tr id="13">
<td>INDUSTRIAL DEFENDER INC</td>
<td>FOXBOROUGH</td>
<td>Chestnut Street</td>
<td nowrap>
<a class="btn small editCompany" href="/PLATON/Admin/Company/Edit/13" id="13">Modifier</a>
<a class="btn small deleteCompany" href="/PLATON/Admin/Company/Delete/13" id="13">Supprimer</a>
</td>
</tr>
<tr id="14">
<td>INC CRANE NUCLEAR</td>
<td>GEORGIA KENNESAW</td>
<td>cobb International Blvd</td>
<td nowrap>
<a class="btn small editCompany" href="/PLATON/Admin/Company/Edit/14" id="14">Modifier</a>
<a class="btn small deleteCompany" href="/PLATON/Admin/Company/Delete/14" id="14">Supprimer</a>
</td>
</tr>
That's ok for me.
How can I get the link at the bottom #LoadMoreLink from the response variable?
I tried:
alert($("#LoadMoreLink",response));
But it didn't work.
Your response contains 2 "parent" elements, the <table>, and the <a>. $(response) creates a jQuery object with 2 elements. To get the one you want, try this:
$(response).filter('#LoadMoreLink')
.find doesn't work here, as .find only searches children, not the "parent" elements themselves. You need to use .filter to search for the "parent" element.
(By "parent" element, I mean the element that's actually in the jQuery object).
$("a", response).filter("[id='LoadMoreLink']")
Should be what you need. I think the normal search is failing because jQuery tries to access the DOM hash of elements with IDs, which "#LoadMoreLink" is not in (having not been loaded into the DOM yet).
If nothing works out then simply load the response in a hidden div and then retrieve $("#LoadMoreLink")
I am trying to clone a template of a which will be populated with data and then inserted into a table. I'm currently able to use the same .clone() function with other elements on the same page but jQuery refuses to see and clone the template (I'm guessing because its not a block element).
Here is the template:
<tr id="search_result_temp" class="template">
<td class="logo">
<img class="logo" />
</td>
<td class="ratings">
<p id="rating"></p>
</td>
<td class="programs"></td>
<td class="actions">
<button id="request_info">Request Info</button>
<button id="save_school">Save</button>
</td>
<td class="compare"></td>
</tr>
Here is the javascript code:
for(var index in results){
var result = results[index];
$result_listing = $("#search_result_temp").clone().removeClass('template').attr('id', result.key);
$search_results.append($result_listing);
}
Thanks!
Found the answer. The clone() function works fine when the template <tr> is encapsulated within <table> and <div> elements. As stated below .innerHTML (which jQuery uses in clone()) does not work with table fragments. That means jQuery will not clone a <tr> if it is a root element (whose parent element is <body>). Therefore, the template should look like this(of course with an appropriate id on the <div> to be selected by jQuery):
<div>
<table>
<tr id="search_result_temp" class="template">
<td class="logo">
<img class="logo" />
</td>
<td class="ratings">
<p id="rating"></p>
</td>
<td class="programs"></td>
<td class="actions">
<button id="request_info">Request Info</button>
<button id="save_school">Save</button>
</td>
<td class="compare"></td>
</tr>
</table>
</div>
for(var index in results){
var result = results[index];
$result_listing = $("#search_result_temp").clone().removeClass('template').attr('id', result.key);
$search_results.append($result_listing);
}
correct me if I'm wrong, but why do you need to
var result = results[index];
index is already a single element of results
Alternatively you can wrap the template in a hidden DIV and access the content via jQueries HTML method. On a side note, you might bump heads cloning several items with the same ID. Try use a class approach and add an identifier (Try the new HMTL5 data-* tag attribute).