Как управлять префиксами пространства имен (в частности, пространством имен по умолчанию) в выходных данных XSLT?

Есть ли способ в XSLT управлять выбором префиксов пространства имен в выходных элементах?

В моем конкретном случае я фактически хочу преобразовать ввод, который выглядит как

<h:html xmlns:h='http://www.w3.org/1999/xhtml'
        xmlns:m='http://www.w3.org/1998/Math/MathML'>
....
<h:p>Equation: <m:math>...</m:math></h:p>

в

<html xmlns='http://www.w3.org/1999/xhtml'>
....
<p>Equation: <math xmlns='http://www.w3.org/1998/Math/MathML'>...</math></p>

То есть преобразование идентичности, которое просто изменяет префиксы пространства имен, чтобы использовать пространство имен по умолчанию для элементов XHTML и MathML по мере необходимости.

Это завершающий шаг в конце рабочего процесса с использованием чистого XML. Вышеупомянутое, конечно, эквивалентно в терминах XML и, следовательно, в терминах XHTML, но браузеры, похоже, не всегда знают об этом (в моих не очень систематических тестах Firefox справляется с обоими вышеперечисленными в смысле рендеринга их как математики — Браво, Firefox! — Safari справляется со вторым, но не с первым, Chrome тоже не справляется; на самом деле я ориентируюсь на читателей EPUB, но кажется мудрым пессимистично относиться к тамошним парсерам XHTML). Попытка с элементом <output method='html'/> XSLT не влияет на результат. В Руководстве по совместимости с XHTML не упоминаются пространства имен, что довольно удивительно. Добавление объявлений типа документа и даже хак <meta http-equiv=''...> для подсказки application/xhtml+xml, похоже, не имеет никакого значения для поведения браузеров.

В спецификации XSLT 1.0 я не вижу ничего, что бы это контролировало. Упомянутый там псевдоним пространства имен решает другую проблему; игра с пространствами имен по умолчанию в XSLT не дает никаких подсказок, которые libxslt, похоже, склонны принимать. Другие вопросы об обмене стеками (например, этот или этот) в значительной степени связаны с непониманием XSLT и пространств имен. Я уверен, что мне удалось добиться этого в какой-то момент моего долгого прошлого XSLT, но если бы я это сделал, я не смог бы его воскресить.

Я бы предпочел решение в XSLT 1.0 просто потому, что у меня есть инструменты и опыт для быстрого использования, в libxslt и xsltproc (Saxon — действительно замечательная вещь, но я не хочу платить стоимость запуска Java для возможно, множество последовательных преобразований). Это может быть то, что вынуждает меня к более поздней версии XSLT, конечно, если более поздняя версия действительно единственная вещь, которая может помочь.

Из (не очень тщательного) взгляда на спецификацию XSLT 3 (например, раздел 11.1) я не вижу ничего, что явно решает эту проблему.

Если я лаю не по тому дереву или если известно, что процессоры EPUB постоянно лучше осведомлены о пространствах имен, так что я на самом деле решаю не ту часть проблемы, я также открыт для этой информации.

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
76
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вам понадобится преобразование

<xsl:template match = "*">
  <xsl:element name = "{local-name()}" namespace = "namespace-uri()">
     <xsl:apply-templates select = "@* | node()"/>
  </xsl:element>
</xsl:template>

Настройте шаблон преобразования удостоверений для остальных.

И в XSLT 1 вы как бы полагаетесь на милость процессора XSLT и его сериализатора, чтобы получить желаемый результат, но я думаю, что для приведенного выше шаблона вы можете ожидать некоторой согласованности даже в мире 1.0.

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

Norman Gray 10.12.2020 19:19

Это действительно очень хорошо работает на практике, в том смысле, что это, кажется, дает сериализатору достаточно подсказок. Сериализатор не полностью понимает подсказку (как вы предлагаете): любые шаблоны, обрабатываемые в этой конструкции, которые содержат, например, <h:p xmlns:h='http://www.w3.org/1999/xhtml'>...</h:p>, к сожалению, сериализуются с этим префиксом, а не с префиксом по умолчанию, который все еще находится в области действия на тот момент. Это означает, что я не могу оставить элементы XSLT в пространстве имен по умолчанию, но... я буду жить. Спасибо, Мартин, что успокоил меня, я ничего не упускаю.

Norman Gray 16.12.2020 18:35

Другие вопросы по теме