Documentation/Source example
Example source
samples/basic/ParseHtml.js
Referenced by:utils.ParseHtml
//
// Demonstrates utils.ParseHtml(), HtmlDocument, and HtmlNode.
//
function log_section(title) {
console.log("");
console.log("=== " + title + " ===");
}
function normalize_text(s) {
return (s || "").replace(/\s+/g, " ").trim();
}
// This example uses the same structure as samples/basic/html/parse_test.html.
// const html = utils.ReadUTF8(`${fb.ComponentPath}\\samples\\basic\\html\\parse_test.html`);
const html = `
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Lexbor Parser Test</title>
<meta property="og:title" content="Test Artist Biography">
</head>
<body>
<main id="page" class="artist-page biography">
<h1 class="artist-name">Test Artist</h1>
<section class="wiki-content" data-source="lastfm">
<p>
Test Artist is an experimental music project from London.
The project combines <strong>ambient</strong>, <em>industrial</em>,
and electronic music.
</p>
<p>
Their first album,
<a href="/music/Test+Artist/First+Album" class="album-link">First Album</a>,
was released in 2020.
</p>
</section>
<section class="albums">
<h2>Albums</h2>
<ul class="album-list">
<li class="album" data-year="2020">
<a href="/music/Test+Artist/First+Album">First Album</a>
</li>
<li class="album featured" data-year="2022">
<a href="/music/Test+Artist/Second+Album">Second Album</a>
</li>
<li class="album" data-year="2024">
<span>No link album</span>
</li>
</ul>
</section>
<section class="external-links">
<h2>External links</h2>
<ul>
<li>
text before link
<a href="https://example.com/artist" rel="external">Official site</a>
</li>
<li>
<!-- comment before link -->
<a href="https://musicbrainz.org/artist/test">MusicBrainz</a>
</li>
<li>
<span>Broken item without href</span>
</li>
</ul>
</section>
</main>
</body>
</html>
`;
const doc = utils.ParseHtml(html);
if (!doc) {
console.log("Parse failed.");
} else {
log_section("Document basics");
console.log("documentElement tag:", doc.documentElement.tagName); // html
console.log("root tag:", doc.root.tagName); // html
console.log("head innerHTML:", normalize_text(doc.head.innerHTML));
console.log("body text:", normalize_text(doc.body.textContent));
log_section("querySelector");
const title = doc.querySelector("title");
console.log("title:", title ? title.textContent : "<missing>");
const artistName = doc.querySelector(".artist-name");
console.log("artist:", artistName ? artistName.textContent : "<missing>");
const wiki = doc.querySelector(".wiki-content");
if (wiki) {
console.log("wiki source:", wiki.getAttribute("data-source")); // lastfm
console.log("wiki text:", normalize_text(wiki.textContent));
}
log_section("querySelectorAll");
const albums = doc.querySelectorAll(".album");
console.log("albums count:", albums.length); // 3
for (let i = 0; i < albums.length; i++) {
const album = albums[i];
const link = album.querySelector("a");
console.log(
"album #" + (i + 1) + ":",
"year=" + album.getAttribute("data-year"),
"featured=" + album.hasClass("featured"),
"title=" + (link ? normalize_text(link.textContent) : normalize_text(album.textContent)),
"href=" + (link ? link.getAttribute("href") : "<no link>")
);
}
log_section("Attribute selectors");
const nodesWithClass = doc.querySelectorAll("[class]");
console.log("nodes with class:", nodesWithClass.length);
const featuredAlbums = doc.querySelectorAll(".album.featured");
console.log("featured albums:", featuredAlbums.length);
const albumToken = doc.querySelectorAll("[class~='album']");
console.log("[class~='album']:", albumToken.length);
log_section("getElementsByTagName");
const allLinks = doc.getElementsByTagName("a");
console.log("all links:", allLinks.length);
for (let i = 0; i < allLinks.length; i++) {
console.log(
"#" + (i + 1),
normalize_text(allLinks[i].textContent),
"=>",
allLinks[i].getAttribute("href")
);
}
log_section("children vs childNodes");
const p = doc.querySelector(".wiki-content p");
console.log("p.children.length:", p.children.length);
console.log("p.childNodes.length:", p.childNodes.length);
// firstChild is a text node here. JSON.stringify() is used intentionally
// to show that original whitespace and line breaks are preserved.
console.log("p.firstChild text:", JSON.stringify(p.firstChild.textContent));
log_section("Safe link extraction");
const externalItems = doc.querySelectorAll(".external-links li");
for (let i = 0; i < externalItems.length; i++) {
const li = externalItems[i];
// Do not use li.firstChild.getAttribute("href"):
// firstChild can be a text node or a comment.
const a = li.querySelector("a[href]");
if (!a) {
console.log("external item #" + (i + 1) + ": no link");
continue;
}
console.log(
"external item #" + (i + 1) + ":",
normalize_text(a.textContent),
"=>",
a.getAttribute("href")
);
}
log_section("Missing nodes");
console.log("missing node:", doc.querySelector(".missing")); // null
console.log("missing list length:", doc.querySelectorAll(".missing").length); // 0
}