@nimfai
Full stack developer

Как преобразовать HTML строку в массив?

У нас на проекте есть wiki на англ. языке, в которую хотим автоматом через Deepl API добавить русские преводы.
А БД текст хранится в виде HTML.
Задача какзалась простой, просто передать эту строку в Deepl и сохранить перевод в БД. Сам переводчик хорошо видит html разметку и в 90% случаев возвращает хороший перевод. Однако если в html есть код (тег code), то, например MySQL код, переводчик переводит его тоже. Мы решили разбить html по тегам и преобразовать его в массив.
const jsdom = require('jsdom')
const dom = new JSDOM(html)
let arr = [...dom.window.document.body.children].map((child) => child.outerHTML)

На выходе имеем, что-то вроде:
[
  "<p>Пример</p>",
  "<co d e class="hljs language-css">.test {text-decoration: none;}</co d e>",
  "<co d e class="hljs javascript">console.log('Test');</co d e>",
  "<p>Пример</p>"
]

В итоге получаем массив и можем обойти его, и перевести только то, что необходимо. Всё работало отлично пока мы не заметили что иногда из кода, который находится в теге code стали пропалать куски кода. Особенно часто это происходит с html кодом.

Вопрос в том, может кто подсказать более универсальный способ перевести html строку, в который есть текст и код?

Заранее спасибо!

UPD: уточню задачу. Есть html строка. Для примера скопировал со StackOverflow:
<p>This is my docker-compose.yml file</p>
<pre><code>version: &quot;3.7&quot;
services: 
  db:
    build: database
    container_name: db
    environment:
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      POSTGRES_DB: ${POSTGRES_DB}
    volumes:
      - ./pgdata:/var/lib/postgressql/data
      - ./database/migrations:/migrations
    ports:
      - &quot;5432:5432&quot;
</code></pre>
<p>My end objective is that it should first run the parent's entry point command and then run mine.</p>


Как из неё получить массив вида:
const arr = [
  "<p>This is my docker-compose.yml file</p>",
  "<pre><code>version: &quot;3.7&quot;
services: 
  db:
    build: database
    container_name: db
    environment:
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      POSTGRES_DB: ${POSTGRES_DB}
    volumes:
      - ./pgdata:/var/lib/postgressql/data
      - ./database/migrations:/migrations
    ports:
      - &quot;5432:5432&quot;
</code></pre>",
  "<p>My end objective is that it should first run the parent's entry point command and then run mine.</p>"
];


При этом, если внутри тега code есть ещё html, то его не должно зацепить. Так как сейчас именно это и происходит.
  • Вопрос задан
  • 360 просмотров
Пригласить эксперта
Ответы на вопрос 1
sasha-hohloma
@sasha-hohloma
Fullstack Developer
Рекомендую почитать что-нибудь про работу с древовидными структурами данных или про парсинг JSON-строки, потому что ваша задача как раз об этом. Могу посоветовать воспользоваться библиотекой htmlparser2, там вы можете контролировать парсинг по необходимых тегам или их атрибутам. В качестве эксперимента можно попробовать вырезать <code>*</code>, но главное не забыть позицию, чтобы потом поставить обратно
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы