I am able to get element text only when tr or td tag is wrapped in table.
Doesn't work
const cheerio = require('cheerio');
const $ = cheerio.load('<td>Hello world</td>');
console.log($('td').text());
Works fine
const cheerio = require('cheerio');
const $ = cheerio.load('<table><td>Hello world</td></table>');
console.log($('td').text());
Why is that?
One good way to get a sense for what Cheerio is doing is by using the static html method to render the document element. Here's how you could do that with your first example:
const cheerio = require('../cheerio');
const $ = cheerio.load('<td>Hello world</td>');
console.log(cheerio.html($('html')));
That returns <html><head></head><body>Hello world</body></html>.
Cheerio interprets the string passed to load as an HTML document. A <td> element can't be a direct descendent of the <body> element, so the permissive nature of HTML ends up producing a document with just a <body> element. This is the same thing your web browser will do if you load a file like that.
Your second example works as expected because it is valid markup--a <td> element may be a direct descendant of a <table> element.
If you want to create document fragments, you can start with an empty document and then use the same approach you would use with jQuery:
const cheerio = require('../cheerio');
const $ = cheerio.load('');
const $td = $('<td>Hello world</td>');
console.log(cheerio.html($td));
That produces the markup you're expecting.
Very well explained @jugglinmike, thank you!
Most helpful comment
One good way to get a sense for what Cheerio is doing is by using the static
htmlmethod to render the document element. Here's how you could do that with your first example:That returns
<html><head></head><body>Hello world</body></html>.Cheerio interprets the string passed to
loadas an HTML document. A<td>element can't be a direct descendent of the<body>element, so the permissive nature of HTML ends up producing a document with just a<body>element. This is the same thing your web browser will do if you load a file like that.Your second example works as expected because it is valid markup--a
<td>element may be a direct descendant of a<table>element.If you want to create document fragments, you can start with an empty document and then use the same approach you would use with jQuery:
That produces the markup you're expecting.