Как получить тег списка в виде массива объектов, используя XPath? - PullRequest
0 голосов
/ 10 февраля 2020

Я пытаюсь извлечь упорядоченный список и вернуть массив тегов списка и содержимого внутри. Я уже пробовал эти пути,

  1. //li[div/@class="business-info"]
  2. //li[div[@class="business-info"]]
  3. //li[descendant::div[@class="business-info"]]
  4. //li[div[@class="business-info"]/h2/a]

Это правильный подход или я должен go с RegExp? Я делюсь своим кодом , чтобы получить детализацию.

Код

const IGNORE = ['style', 'script'];
const NONWHITESPACE_RE = /\S/;
const result = document.evaluate(
    '//*[child::text()]',
    document,
    null,
    XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
    null
);
const businessInfo = [];
for (let i = 0, j = result.snapshotLength; i < j; i++) {
    const element = result.snapshotItem(i);
    if (IGNORE.includes(element.tagName.toLowerCase())) {
        continue;
    }
    const nodes = [...element.childNodes];
    for (const node of nodes) {
        if (node.nodeType !== document.TEXT_NODE) {
            continue;
        }
        if (node.nodeValue.search(NONWHITESPACE_RE) === -1) {
            continue;
        }
        businessInfo.push({
            tag: element.tagName.toLowerCase(),
            text: node.nodeValue.trim()
        });
    }
}
console.log(businessInfo);

HTML

<ol class="results">
    <li class="result clearfix">
        <div class="business-info">
            <h2 itemprop="name">
                <a class="name" href="#">Company Ltd</a>
            </h2>
            <a href="#" class="phone disabled"><span class="tel-icon sprite"></span><span itemprop="telephone" class="phone">0123456789</span></a>
            <div class="address">
                <span class="address-main"><span itemprop="streetAddress">21 Largo Road</span>, <span itemprop="addressLocality">Focus</span>, </span>
                &nbsp;<span class="postcode" itemprop="postalCode">KY168NH</span>
            </div>
        </div>
    </li>
    <li class="result clearfix">
        <div class="business-info">
            <h2 itemprop="name">
                <a class="name" href="#">Shipment Ltd</a>
            </h2>
            <a href="#" class="phone disabled"><span class="tel-icon sprite"></span><span itemprop="telephone" class="phone">0123456789</span></a>
            <div class="address">
                <span class="address-main"><span itemprop="streetAddress">ECR Road</span>, <span itemprop="addressLocality">St Andrews</span>, </span>
                &nbsp;<span class="postcode" itemprop="postalCode">800826</span>
            </div>
        </div>
    </li>
</ol>

Ожидаемый результат: Массив объектов

const businessInfo = [
    {
        name: 'Company Ltd',
        phone: '0123456789',
        address: '21 Largo Road',
        locality: 'Focus',
        postal: 'KY168NH'
    },
    {
        name: 'Company Ltd1',
        phone: '0123456789',
        address: 'ECR Road',
        locality: 'St Andrews',
        postal: '800826'
    },
];

Это источники, которые я взял для справки

  1. https://developer.mozilla.org/en-US/docs/Web/API/XPathResult/snapshotItem
  2. https://developer.mozilla.org/en-US/docs/Web/API/XPathResult/iterateNext
  3. Получить XPath XML Tag

1 Ответ

0 голосов
/ 10 февраля 2020

Похоже, что в моем случае XPath не нужен, я решил его, найдя innerText для каждого свойства с помощью селектора. И тогда я составил массив объектов с этими свойствами. Теперь результат будет таким, как я ожидал.

const businessInfo = [];
const elements = document.querySelectorAll('ol > li > div.business-info');
elements.forEach((element) => {
    const companyInfo = {};
    try {
        businessInfo.name = element.querySelector('h2 > a').innerText;
        businessInfo.phone = element.querySelector('a > span.phone').innerText;
        businessInfo.address = element.querySelector('div > span.address-main > span:nth-child(1)').innerText;
        businessInfo.locality = element.querySelector('div > span.address-main > span:nth-child(2)').innerText;
        businessInfo.postalCode = element.querySelector('div > span.postcode').innerText;
    } catch (exception) {

    }
    data.push(businessInfo);
});
console.log(businessInfo);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...