XSLT IE11 преобразует узел <param> в самозакрывающийся тег без закрытия

Этот вопрос очень актуален для этого XSLT преобразует узел <image> в тег <img> при выводе в DOM

Рассмотрим этот фрагмент кода:

<script type = "application/xml" id = "data">
    <xsl:copy-of select = "/*" />
</script>

Это выведет содержимое XML-документа на html-страницу. Тогда очень легко анализировать данные из XML с помощью объекта DOMParser() в javascript, что делает их легко доступными на веб-странице без необходимости использования XSLT для создания веб-страницы.

Перемещение <xsl:copy-of select"/*" /> между тегами сценария требовалось, чтобы преобразователь XSLT не преобразовывал узел в файле XML в теги HTML.

Это работало отлично, пока я не узнал, что то же самое происходит и с узлом. Проще говоря: если у XML есть узел, вывод будет испорчен и не поддается анализу, например:

Как предотвратить такое поведение? Как запретить движку браузера делать тег самозакрывающимся?

new DOMParser().parseFromString()

/\ Не будет работать с самозакрывающимися узлами. (ПОЯСНЕНИЕ: очевидно, что DOMParser БУДЕТ работать с самозакрывающимися узлами, просто в этом случае он не был самозакрывающимся, т.е. не имел косой черты)


Итак, вот файлы, которые необходимы для воспроизведения этого:

test.xslt

<?xml version = "1.0" encoding = "UTF-8"?>
<xsl:stylesheet xmlns:xsl = "http://www.w3.org/1999/XSL/Transform" version = "1.0">

    <xsl:output method = "html" indent = "no" version = "5.0" />

    <xsl:template match = "/">
        <xsl:text disable-output-escaping='yes'>&lt;!DOCTYPE html></xsl:text>
        <xsl:apply-templates select = "root" />
    </xsl:template>

    <xsl:template match = "root">
        <html>
            <head>
                <script type='application/xml'>
                    <xsl:copy-of select = "/*" />
                </script>
            </head>
            <body>
                <div>qwe</div>
            </body>
        </html>
    </xsl:template>

</xsl:stylesheet>

test.xml

<?xml version = "1.0" encoding = "UTF-8"?>
<?xml-stylesheet type = "text/xsl" href = "test.xslt"?>

<root>
    <object>
        <text>text</text>
        <param name = "name"></param>
    </object>
</root>

Откройте test.xml с помощью Edge в режиме совместимости с Internet Explorer 11. В "голове" должен быть скрипт с искаженным xml.

В Windows 10 вы можете открыть Инструменты разработчика, выполнив «Выполнить (Win+R)» -> «%systemroot%\system32\f12\IEChooser.exe» после открытия XML-файла.

Какова среда для запуска XSLT/XPath, которая выполняет <xsl:copy-of select = "/*" />? В идеале содержимое элемента script должно быть сериализовано в формате XML. Сложно в XSLT 1, но есть библиотеки XSLT 1.0 для сериализации и/или с помощью MSXML в IE, возможно, можно будет вызвать J(ava)Script для сериализации узла.

Martin Honnen 11.04.2024 15:58

Возможная чистая сериализация XML в формате XSLT 1 — lenzconsulting.com/xml-to-string.

Martin Honnen 11.04.2024 15:59

Я просто открываю XML-файл с помощью Edge в режиме совместимости с IE11. *.xslt файл со всеми шаблонами находится в одной папке

Glenn Carver 11.04.2024 16:11

Но вы используете как преобразование XSLT на основе xml-stylesheet pi в некоторых XML, так и более позднее преобразование XSLT, запускаемое Javascript? Мне не понятна вся последовательность обработки, в каком моменте вы используете элемент script с xsl:copy-of внутри и где вам потом нужно обрабатывать содержимое элемента скрипта. Но в XSLT 1, если вам нужно сериализовать узел XML, используйте библиотеку, которая может это сделать.

Martin Honnen 11.04.2024 16:15

Не важно. Я обновил вопрос, включив в него содержимое двух файлов — test.xml и test.xslt. Я просто открываю test.xml с помощью Edge в режиме IE11 и все. У меня на компьютере установлен MSXML4, если это что-то меняет (я установил его, потому что директива <xsl:include> без него не работала). Полагаю, мне все-таки придется использовать библиотеки.

Glenn Carver 11.04.2024 16:59

Будем надеяться, что кто-нибудь сможет вам помочь. Мне кажется, что Edge в Windows 11 полностью основан на Chromium, и у меня даже нет возможности включить режим совместимости с IE. Запуск XSLT на основе файла с таблицей стилей xml не поддерживается в Edge или Chromium.

Martin Honnen 11.04.2024 19:09
Стоит ли изучать 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
6
75
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Что касается моего предложения по сериализации с использованием библиотеки, вот как это будет выглядеть (при реальном использовании не импортируйте через HTTP(S), используйте локальную копию xsl:import):

<xsl:stylesheet xmlns:xsl = "http://www.w3.org/1999/XSL/Transform"
  version = "1.0">

  <xsl:import href = "https://lenzconsulting.com/xml-to-string/xml-to-string.xsl"/>

  <xsl:output method = "html" indent = "no" version = "5.0" doctype-system = "about:legacy-doctype" />

  <xsl:template match = "/">
    <xsl:apply-templates/>
  </xsl:template>
  
  <xsl:template match = "root">
      <html>
          <head>
              <script type='application/xml'>
                  <xsl:apply-templates select = "." mode = "xml-to-string"/>
              </script>
          </head>
          <body>
              <div>qwe</div>
          </body>
      </html>
  </xsl:template>

</xsl:stylesheet>

Это должно дать вам элемент script, который в качестве текстового/CDATA-содержимого имеет сериализацию элемента root входного документа.

Что касается способа сериализации пустых элементов, в XML это не имеет значения, но библиотека позволяет вам установить <xsl:param name = "use-empty-syntax" select = "false()"/>, чтобы получить, например. <param name = "name"></param>.

Ты снова спас мою шкуру. Эта библиотека полностью работает и делает то, что нужно. Единственная причуда, которую я обнаружил, заключается в том, что тег <param> закрывается, если он пуст, что делает его самозакрывающимся тегом. Но это нормально, поскольку DOMParser ДЕЙСТВИТЕЛЬНО работает с самозакрывающимися узлами. Итак, результат: xml <object> <param name = "name" /> </object> По какой-то причине он не делает этого для других пустых узлов.

Glenn Carver 12.04.2024 10:14

Единственное, чего я боюсь, это потерять эту библиотеку, если сайт выйдет из строя :) (я скачал ее для локального использования, но все же - что, если кто-то еще столкнется с той же проблемой, но решение недоступно)

Glenn Carver 12.04.2024 10:15

@GlennCarver, библиотека позволяет вам установить параметр use-empty-syntax на false(), чтобы пустые элементы были сериализованы с помощью начального и конечного тега. Что касается закрытия сайта, будем надеяться, что Эван продолжит его работу. Конечно, с 2017 года мы живем в мире XSLT 3, где есть встроенная функция XPath 3.1 fn:serialize, поддерживаемая на широком спектре платформ и в широком спектре сред такими реализациями, как Saxon Java, SaxonC, SaxonJS, Saxon. NET и различные инструменты Altova XML (XML Spy, Raptor), поэтому существуют современные компактные альтернативы. Однако не уверен, что есть способ для IE.

Martin Honnen 12.04.2024 10:29

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