0

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.

1

6 Answers 6

7

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
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for this quick reference
1

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());​​​

Comments

1

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') );

4 Comments

You don't want to try to parse HTML fragments as XML. Not unless you know they're valid XHTML. Moreover, this isn't the problem.
@T.J.Crowder Probably you are right, however sometimes it can be useful.
@dfsq Its good but actually the string I'm getting is from another website which is not valid XHTML. I just need to find content inside a div tag but cannot parse it to xml. Any ideas how to do this now.
DOMParser can proccess even non valid HTML as far as I know.
0

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());​

1 Comment

I don't think that's what he means.
0

Try below code:

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

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

1 Comment

@harsh4u Someone may explain this logic.
0

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!

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.