XML со стилями: почему карта сайта выглядела сломанной и при чём тут hreflang
Карта сайта открывалась в браузере одной плоской строкой. Причина — пространство имён XHTML внутри XML. Разбор, починка через XSL и ловушка с типом отдачи файла.
Открываешь свою карту сайта в браузере — вместо дерева тегов одна слитная строка с адресами и датами. У соседнего сайта та же карта показывается аккуратным деревом. Файл при этом валиден, парсер разбирает его без ошибок, роботы читают нормально.
Причина: пространство имён XHTML
Разница была в одной строке объявлений. В моей карте есть hreflang-связки — теги, которые сообщают поисковику, что русская и английская версии страницы это одна страница на двух языках. Они живут в пространстве имён XHTML, и оно объявлено в корне документа.
Как только браузер видит объявленное пространство имён XHTML, он перестаёт считать файл «просто XML» и пытается отрисовать его как страницу. А для страницы теги loc, lastmod и priority — обычные строчные элементы без стилей, поэтому весь текст сливается в один абзац.
Проверил это экспериментом: взял ту же карту, убрал объявление и сами связки, открыл оба файла в одном браузере. Первый — плоская строка, второй — дерево.
1<?xml version="1.0" encoding="UTF-8"?>
2<?xml-stylesheet type="text/xsl" href="/sitemap.xsl"?>
3<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
4 xmlns:xhtml="http://www.w3.org/1999/xhtml">
5 <url>
6 <loc>https://example.com/</loc>
7 <xhtml:link rel="alternate" hreflang="ru" href="https://example.com/"/>
8 <xhtml:link rel="alternate" hreflang="en" href="https://example.com/en"/>
9 <lastmod>2026-08-13</lastmod>
10 </url>
11</urlset>
Починка: таблица стилей для XML
К карте прикладывается XSL — преобразование, которое превращает её в человекочитаемую таблицу. XSLT 1.0, потому что это всё, что когда-либо поддерживали браузеры. Стили внутри файла: он запрашивается отдельно, и никакого CSS сайта для него не существует.
Есть оговорка на будущее: в Chrome обсуждают отказ от XSLT. Если его уберут, карта вернётся к плоскому виду — то есть терять нечего, а для роботов не изменится ничего.
Ловушка: тип отдачи файла
После починки я открыл сам файл стилей — и получил страницу с заголовком сайта и пустой таблицей. Первая догадка была, что браузер применяет таблицу к самой себе, и я добавил в неё ветку «если карты нет, скажи, что ты таблица стилей».
Проверил — стало хуже: на странице появились оба блока сразу. Значит, браузер не выполняет преобразование, а просто печатает всю разметку, которую находит внутри файла, игнорируя xsl-элементы. Средствами XSLT это не лечится вовсе.
Лечится типом отдачи. Инструкция внутри карты называет text/xsl, и именно на неё браузер опирается, решая применить стили; сам файл должен всего лишь разбираться как XML. Поэтому отдаю его как application/xml: карта оформляется по-прежнему, а открытый напрямую файл показывается тем, чем является — исходником.
| Тип отдачи .xsl | Карта оформляется | Сам файл открывается как |
|---|---|---|
| text/xsl | да | сломанная страница |
| application/xml | да | дерево исходника |
| не указан | нет | поток байтов |
