Sukanta Paul
Sukanta Paul

Reputation: 792

Cannot parse HTML with jQuery

I want to parse home HTML like the following using jQuery. When I'm using document it is working. But not working when using string.

Output: null

var str = "<html><title>This is Title</title><body><p>This is a content</p><p class='test'>Test content</p></body></html>";
$str = $(document); // working
$str = $(str);      // not working
alert($str.find(".test").html());

Another method (also fails):

Output: null

var str = "<html><title>This is Title</title><body><p>This is a content</p><p class='test'>Test content</p></body></html>";
alert($('.test',str).html());

The string I'm getting also cannot be parsed as XML as it is not a valid XHTML.

Upvotes: 0

Views: 3213

Answers (6)

Sukanta Paul
Sukanta Paul

Reputation: 792

Okay, as it is not valid XHTML I cannot parse into XML. But still I got an easy silly solution to achieve what I wanted.

var str = "<html><title>This is Title</title><body><p>This is a content</p><p class='test'>Test content</p></body></html>";

//-- replace with document or whatever which will not conflict ---------
str = str.replace(/html>/gi,'document>');

alert($(str).find('.test').html());

Output: Test content.

May be its not a proper way. But still it works great!

Thank you @T.J. Crowder. I got the Idea from the concept jQuery can only parse HTML fragments. So, we can fake to achieve this!

Upvotes: 0

dfsq
dfsq

Reputation: 193301

Try this:

var str = "<html><title>This is Title</title><body><p>This is a content</p><p class='test'>Test content</p></body></html>";
console.log($($.parseXML(str)).find('.test'));

So you parse your string as XML first.

UPD. As T.J.Crowder pointed in comments you have to be sure that your HMTL string is valid XHTML.

And using power of plain JS it could be:

var parser, xml,
    str = "<html><title>This is Title</title><body><p>This is a content</p><p class='test'>Test content</p></body></html>";

if (window.DOMParser) {
    parser = new DOMParser();
    xml = parser.parseFromString(str, "text/xml");
}
else { // IE
    xml = new ActiveXObject("Microsoft.XMLDOM");
    xml.async = "false";
    xml.loadXML(str);
}

console.log( $(xml).find('.test') );

Upvotes: 1

harsh4u
harsh4u

Reputation: 2610

Try below code:

$(str).find(".test").html();

use str variable directly...not to assign in variable..

Upvotes: 0

Michal Klouda
Michal Klouda

Reputation: 14521

The problem is that your string contains full HTML document..

This would work:

var str = "<div><p>This is a content</p><p class='test'>Test content</p></div>";
alert($(str).find('.test').html());​​​

Upvotes: 1

T.J. Crowder
T.J. Crowder

Reputation: 1075755

jQuery can turn HTML fragments into trees of DOM elements, but it only does that with content elements, not html, title, head, etc. Only the things you would put inside body. So that's probably causing some trouble to start with.

The find function looks for descendant elements that match the given selector. So even if any of the top-level elements in a jQuery instance match the selector, they are not found by find. E.g.:

$('<p class="foo">foo</p>').find('.foo').length; // 0 -- none found

...because the matching element isn't a descendant. To find elements at the top level that match, use filter:

var str = "<p>This is a content</p><p class='test'>Test content</p>";
$(str).find('.test').length; // 0 -- no *descendants* found that match
$(str).filter('.test').length; // 1 -- there was one top-level element that matched

Another approach is to put all of your elements in a container, like a div, before using find:

var str = "<div><p>This is a content</p><p class='test'>Test content</p></div>";
$(str).find('.test').length; // 1 -- it was found

Upvotes: 7

Palpatim
Palpatim

Reputation: 9272

You're so close! :) The $(document) line returns a jQuery set; you don't need to do any additional conversion on it.

$str = $(document); // working
alert($str.find(".test").html());​

Upvotes: 0

Related Questions