Html document node js

server-queryselector aka парсим html в nodejs

Разбиваем строку кссселекторов по разделителям, определяем какой это кссселектор, обрезаем и создаем дерево.

class cssSelectorParser < parse(str) < let res = []; str = this.utils.lex(str); for (var i = 0; i ); > else if (str[i].includes("#")) < res.push(); > else if (str[i].includes("[")) < let current = str[i]; current = current.substring(1); current = current.slice(0, -1); current = current.split(" ." || str[i + 1] === '#' || str[i + 1] === '>' || str[i + 1] === '[' || (str[i] === ' ')) < res += "\n"; >else if (str[i + 1] === " ") < res += "\n" >> return res.split("\n"); > > >

3.2) Теперь отфильтруем дом_ноды по кссселекторам

class treeWorker < //Текущий массив дом_ноде _tree; //Построить массив элементов всех детей ноды setCurrentTreeByNode(node) < let tree = this._getChildrens([node]); this._tree = tree; >//Основной цикл, где мы и фильтруем dom по дереву кссселекторов filtredBySelector(selector) < let cssselectorParser = new cssSelectorParser(); selector = cssselectorParser.parse(selector); let res; for (let i = 0; i '); if (isArrowSelector) < continue; >for (var j = 0; j < currentSelector.length; j++) < key = currentSelector[j].key item = currentSelector[j].value; this._filtredByAttribute(key, item) >res = this._tree; let nextSelectorArrow = selector[i + 1] && selector[i + 1][0] && selector[i + 1][0].value === '>'; this._sliceChildrens(nextSelectorArrow) > return res; > //Построить весь хтмл ноды getInnerHTML(dom_node, cliFormat = false) < let res = ''; let lvl = -1; function deep(node) < let leftMargin = ''; for (let i = 0; i res += leftMargin + '" res += (cliFormat) ? "\n" : ""; res += (cliFormat && node.innerTEXT !== '') ? leftMargin + ' ' : ''; res += node.innerTEXT; res += (cliFormat && node.innerTEXT !== '') ? "\n" : ""; node.childrens.forEach((childNode) => < lvl++; deep(childNode); lvl--; >); res += leftMargin + ''; res += (cliFormat && lvl !== -1) ? "\n" : ""; > deep(dom_node); return res; > //Фильтрация текущего массива дом_ноде по аттрибутам _filtredByAttribute(_key, _value) < this._tree = this._tree.filter((item) => < let currentAttr = item.attr.find((attr) =>attr.key === _key); if (currentAttr) < return currentAttr.value.includes(_value.trim()) >>); > //Получить детей(первый срез или весь) текущего массива дом_ноде _sliceChildrens(firstChild = false) < let res = []; if (firstChild) < for (let i = 0; i > else < res = this._getChildrens(this._tree) >this._tree = res; > //Получить всех детей дом нод _getChildrens(currentNodes) < //get all childs let allChilds = [. currentNodes]; let queue = [. currentNodes]; while(queue.length)< let item = queue.shift(); for(let i = 0; i > return allChilds; > >

Рассмотрим подробнее — Основной цикл, где мы и фильтруем «текущие элементы dom» по дереву кссселекторов.

Читайте также:  Ubuntu php install with extensions

//
Храним текущие дом_ноды в this._tree, фильтруем их, нарезаем детей, репит

filtredBySelector(selector) < let cssselectorParser = new cssSelectorParser(); //Получаем дерево кссселекторов selector = cssselectorParser.parse(selector); let res; //проходим по дереву for (let i = 0; i '); if (isArrowSelector) < continue; >//проходим по всем элементам текущего кссселектора for (var j = 0; j < currentSelector.length; j++) < key = currentSelector[j].key item = currentSelector[j].value; //фильтруем текущее this._tree по аттрибутам this._filtredByAttribute(key, item) >> res = this._tree; //если следующий элемент - эрров - срезаем только первый слой, если нет - всех детей let nextSelectorArrow = selector[i + 1] && selector[i + 1][0] && selector[i + 1][0].value === '>'; this._sliceChildrens(nextSelectorArrow) > return res; >

Эти сущности и выполняют основную работу, теперь создадим входную сущность documentServer.

class documentServer < builderDOM = new BuilderDOM(); domTreeWorker; startNode; querySelector(selector) < this.domTreeWorker.setCurrentTreeByNode(this.startNode); return this.domTreeWorker.filtredBySelector(selector); >build(str) < this.domTreeWorker = new treeWorker(); global.treeworker = this.domTreeWorker; let dom = this.builderDOM.html_to_dom(str); global.treeworker = null; this.startNode = dom[0]; >>

Осталось реализовать фичу — квериселектор из ноды, поэтому прокинем domTreeWorker в дом_ноду через глобал

class dom_node < childrens = []; innerTEXT = ''; tag; treeWorker; constructor() < this.treeWorker = global.treeworker; >innerHTML = (cliFormat = false) => < return this.treeWorker.getInnerHTML(this, cliFormat); >; querySelector = (selector) => < this.treeWorker.setCurrentTreeByNode(this); return this.treeWorker.filtredBySelector(selector); >> 

Источник

server-queryselector aka парсим html в nodejs

Разбиваем строку кссселекторов по разделителям, определяем какой это кссселектор, обрезаем и создаем дерево.

class cssSelectorParser < parse(str) < let res = []; str = this.utils.lex(str); for (var i = 0; i ); > else if (str[i].includes("#")) < res.push(); > else if (str[i].includes("[")) < let current = str[i]; current = current.substring(1); current = current.slice(0, -1); current = current.split(" ." || str[i + 1] === '#' || str[i + 1] === '>' || str[i + 1] === '[' || (str[i] === ' ')) < res += "\n"; >else if (str[i + 1] === " ") < res += "\n" >> return res.split("\n"); > > >

3.2) Теперь отфильтруем дом_ноды по кссселекторам

class treeWorker < //Текущий массив дом_ноде _tree; //Построить массив элементов всех детей ноды setCurrentTreeByNode(node) < let tree = this._getChildrens([node]); this._tree = tree; >//Основной цикл, где мы и фильтруем dom по дереву кссселекторов filtredBySelector(selector) < let cssselectorParser = new cssSelectorParser(); selector = cssselectorParser.parse(selector); let res; for (let i = 0; i '); if (isArrowSelector) < continue; >for (var j = 0; j < currentSelector.length; j++) < key = currentSelector[j].key item = currentSelector[j].value; this._filtredByAttribute(key, item) >res = this._tree; let nextSelectorArrow = selector[i + 1] && selector[i + 1][0] && selector[i + 1][0].value === '>'; this._sliceChildrens(nextSelectorArrow) > return res; > //Построить весь хтмл ноды getInnerHTML(dom_node, cliFormat = false) < let res = ''; let lvl = -1; function deep(node) < let leftMargin = ''; for (let i = 0; i res += leftMargin + '" res += (cliFormat) ? "\n" : ""; res += (cliFormat && node.innerTEXT !== '') ? leftMargin + ' ' : ''; res += node.innerTEXT; res += (cliFormat && node.innerTEXT !== '') ? "\n" : ""; node.childrens.forEach((childNode) => < lvl++; deep(childNode); lvl--; >); res += leftMargin + ''; res += (cliFormat && lvl !== -1) ? "\n" : ""; > deep(dom_node); return res; > //Фильтрация текущего массива дом_ноде по аттрибутам _filtredByAttribute(_key, _value) < this._tree = this._tree.filter((item) => < let currentAttr = item.attr.find((attr) =>attr.key === _key); if (currentAttr) < return currentAttr.value.includes(_value.trim()) >>); > //Получить детей(первый срез или весь) текущего массива дом_ноде _sliceChildrens(firstChild = false) < let res = []; if (firstChild) < for (let i = 0; i > else < res = this._getChildrens(this._tree) >this._tree = res; > //Получить всех детей дом нод _getChildrens(currentNodes) < //get all childs let allChilds = [. currentNodes]; let queue = [. currentNodes]; while(queue.length)< let item = queue.shift(); for(let i = 0; i > return allChilds; > >

Рассмотрим подробнее — Основной цикл, где мы и фильтруем «текущие элементы dom» по дереву кссселекторов.

//
Храним текущие дом_ноды в this._tree, фильтруем их, нарезаем детей, репит

filtredBySelector(selector) < let cssselectorParser = new cssSelectorParser(); //Получаем дерево кссселекторов selector = cssselectorParser.parse(selector); let res; //проходим по дереву for (let i = 0; i '); if (isArrowSelector) < continue; >//проходим по всем элементам текущего кссселектора for (var j = 0; j < currentSelector.length; j++) < key = currentSelector[j].key item = currentSelector[j].value; //фильтруем текущее this._tree по аттрибутам this._filtredByAttribute(key, item) >> res = this._tree; //если следующий элемент - эрров - срезаем только первый слой, если нет - всех детей let nextSelectorArrow = selector[i + 1] && selector[i + 1][0] && selector[i + 1][0].value === '>'; this._sliceChildrens(nextSelectorArrow) > return res; >

Эти сущности и выполняют основную работу, теперь создадим входную сущность documentServer.

class documentServer < builderDOM = new BuilderDOM(); domTreeWorker; startNode; querySelector(selector) < this.domTreeWorker.setCurrentTreeByNode(this.startNode); return this.domTreeWorker.filtredBySelector(selector); >build(str) < this.domTreeWorker = new treeWorker(); global.treeworker = this.domTreeWorker; let dom = this.builderDOM.html_to_dom(str); global.treeworker = null; this.startNode = dom[0]; >>

Осталось реализовать фичу — квериселектор из ноды, поэтому прокинем domTreeWorker в дом_ноду через глобал

class dom_node < childrens = []; innerTEXT = ''; tag; treeWorker; constructor() < this.treeWorker = global.treeworker; >innerHTML = (cliFormat = false) => < return this.treeWorker.getInnerHTML(this, cliFormat); >; querySelector = (selector) => < this.treeWorker.setCurrentTreeByNode(this); return this.treeWorker.filtredBySelector(selector); >> 

Источник

Оцените статью