LINUX.ORG.RU

Как заставить работать disable-output-escaping

 ,


0

1

Вот что я пытаюсь открывать в Firefox 101.0.1:

<!DOCTYPE html>
<html>
<head>
<title>XSLT over XML both embedded</title>
</head>
<body onload="onload();">

<script id="xsl" language="application/xslt">
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
	<xsl:template match="/">
		<xsl:text disable-output-escaping="yes">&lt;!DOCTYPE html&gt;</xsl:text>
		<html>
			<head>
				<title>title test</title>
			</head>
		<body>
			Article - <xsl:value-of select="/Article/Title"/>
			<br />
			Authors: <xsl:apply-templates select="/Article/Authors/Author"/>
		</body>
		</html>
	</xsl:template>

  <xsl:template match="Author">
    - <xsl:value-of select="." />
  </xsl:template>

</xsl:stylesheet>
</script>

<script id="xml" language="application/xml">
<?xml version="1.0" encoding="utf-8"?>
<Article>
  <Title>My Article</Title>
  <Authors>
    <Author>Mr. Foo</Author>
    <Author>Mr. Bar</Author>
  </Authors>
  <Body>This is my article text.</Body>
</Article>
</script>

<script language="javascript">

    function onload() {
        // Load XSL
        var xsl_source = document.getElementById("xsl").textContent;
	var xslParser = new DOMParser();
	var xsl_doc = xslParser.parseFromString(xsl_source.trimStart(), "text/xml")
	xsltProcessor = new XSLTProcessor();
        xsltProcessor.importStylesheet(xsl_doc);

        // Load XML 
        var xml_source = document.getElementById("xml").textContent; 
	var xmlParser = new DOMParser();
        var xml_doc = xmlParser.parseFromString(xml_source.trimStart(), "application/xml");

        // Transform
	var html = xsltProcessor.transformToDocument( xml_doc ).documentElement.innerHTML;
	var text = html.replace("&lt;!DOCTYPE html&gt;", "<!DOCTYPE html>");

	// Update page
	document.write(text);
    }
</script>

</body>
</html>

Моя проблема в том, что не срабатывает disable-output-escaping=«yes» и мне приходится вызывать html.replace.

Что надо сделать, чтобы вызов replace не требовался?

★★★

Последнее исправление: Shushundr (всего исправлений: 2)

Вообще все не так. Ты пытаешься вывести в браузере валидный xml? Яннп, по-твоему, он должен перерендерить исходник согласно выданному тексту? Как ты вообще представляешь это должно работать? О_о

Upd. Запустил, все сработало. Прикольно. На чем тестишь?

Anoxemian ★★★★★
()
Последнее исправление: Anoxemian (всего исправлений: 1)
Ответ на: комментарий от Shushundr

Ну в общем как и предполагалось. Так не будет работать, надо курить\переопределять в js все эти объекты. Вот твой пример без обмазанного, прямо средствами браузера: https://xmpp.polzi.net/test.xml

В случае с js, очевидно, document.write после начала вывода не переопределит нужного. Не для того оно.

Anoxemian ★★★★★
()

Да просто забей на этот доктайп. К счастью, рендер xml через xslt уже делается в режиме html5, поэтому <!doctype html> явно можно не указывать.

Проверить легко. В Quirks mode значения атрибутов CSS без указания единицы измерения распознаются как px, а в Full standards mode — игнорируются как ошибочные. Таким образом, нижеприведённый div в режиме HTML5 будет иметь ширину 100%:

<div style="background-color: red; width: 400">bad width</div>
static_lab ★★★★★
()
Ответ на: комментарий от Anoxemian

Я не понял, что не так. Вот как я вижу результат по ссылке:

<transformiix:result>&lt;!DOCTYPE html&gt;<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>title test</title></head><body>
        Article - My Article<br>
        Authors: 
  - Mr. Foo
  - Mr. Bar</body></html></transformiix:result>

И мне кажется странным, что здесь DOCTYPE внутри &lt; и &gt;, а не < и >.

Тем более, как видно, что если выполнить replace, то всё начинает работать.

Shushundr ★★★
() автор топика
Ответ на: комментарий от Anoxemian

Есть похожий вопрос на stackoverflow - https://stackoverflow.com/questions/45193032/how-to-remove-transformiixresult...

В нём говорят, что слово <transformiix:result> добавляется только в режиме text. Режим и явно прописать внутрь xsl можно, а вот эти «меньше» и «больше» почему-то выводятся в виде HTML когда работает firefox и выводятся символы когда работает xsltproc.

фуррифокс дуркует

Возможно я его просто неправильно использую? Может ему можно что-то сказать и он всё сделаеть? В чём причина-то его такого поведения?

Shushundr ★★★
() автор топика
Ответ на: комментарий от Anoxemian

очевидно, document.write после начала вывода не переопределит нужного. Не для того оно.

Неправильная гипотеза. Ведь есть засунуть в document.write текст после replace, то всё он переопределяет.

Shushundr ★★★
() автор топика
Ответ на: комментарий от Anoxemian

Я тебе уже ответил, как починить.

Я не понял твой ответ. Ты предложил попробовать в консоли, я попробовал. В консоли нет этих HTML-последовательностей. И в chromium работает, верно. Но это же не починка.

Shushundr ★★★
() автор топика
Ответ на: комментарий от Shushundr

Да, только на этот момент, в браузер уже прилетело все, что было до onload(); Надо по-хорошему, делать заново document.open() или как-то передергивать этот блядский HTMLDcoument.

Anoxemian ★★★★★
()
Ответ на: комментарий от Anoxemian

Надо по-хорошему, делать заново document.open()

Я делал open перед write, даже с двумя параметрами. Это не помогает. Но и не должно, потому что open выполняется автоматически (это я нашел и прочитал на stackoverflow).

Shushundr ★★★
() автор топика
Ответ на: комментарий от Anoxemian

Ну это фактически признание того, что html сформирован неправильно. А document.write нормально работает.

Значит правильное решение - сформировать html правильно.

Shushundr ★★★
() автор топика
Ответ на: комментарий от Shushundr

Значит выкинуть лису на мороз. Ну или решать каким-то хаком. Можно, по-идее в CDATA обернуть, как-то химичить или просто забить. Все равно как выше заметили, кроме дрочева лисы, все работает корректно.

Anoxemian ★★★★★
()
Ответ на: комментарий от Anoxemian

кроме лисы, все работает корректно.

Лиса тоже работает корректно, так как стандарт не жестко требует соблюдать «disable-output-escaping», а по мере возможности. Лиса имеет право (так на stackoveflow написано):

«This will work most of the time, but it is a hack, and it is unlikely (i.e. won't) work as expected if you are not serialising your result back to a text file on disk (e.g. if the result of the transform is being passed on to another process without serialisation).»

Нужно переменную html как-то по-другому заполнить при помощи javascript, чтобы лиса осознала, что от неё хотят.

Shushundr ★★★
() автор топика
Ответ на: комментарий от Anoxemian

doctype-system=«about:legacy-compat»

это лишнее, всё остальное добавлял, не помогает. И я написал, почему не помогает, потому что не должно помочь.

Надо при помощи JavaScript сериализовать и распарсить (но я не могу написать код как это).

Shushundr ★★★
() автор топика
Ответ на: комментарий от Anoxemian

Внезапно, помогло. Даже в лисе.

нет, это «видимость», внешнее впечатление.

Если ты вставишь это в HTML и откроешь Shift-Ctrl+K, то там будет написано:

Эта страница загружена в режиме Quirks. Это может повлиять на макет страницы. Для режима Standards используйте «<!DOCTYPE html>».

Shushundr ★★★
() автор топика
Ответ на: комментарий от Shushundr

Так они и не считают это багом. По идее, это должно быть описано в соответствующем DTD через явное указание CDATA[] и далее по определению html, можно свой dtd вкорячить и посмотреть как это будет выглядеть, но мне впадлу. Еще заметил, что если прописать так:

<xsl:output
     method="html"
     doctype-system=""
     encoding="UTF-8"
     indent="yes" />

то рендер делает вывод точно как ты хочешь <!DOCTYPE html>

Anoxemian ★★★★★
()
Последнее исправление: Anoxemian (всего исправлений: 1)
Ответ на: комментарий от Anoxemian

Что-то я делаю не так.

1) я обновил Firefox до версии 107.0.1, но теперь сообщение выдаётся на английском языке:

This page is in Quirks Mode. Page layout may be impacted. For Standards Mode use “<!DOCTYPE html>”.

2) я посмотрел, можно ли иметь HTML-документы с заголовком

<!DOCTYPE html SYSTEM "">
по стандарту можно - https://stackoverflow.com/questions/67486840/does-an-empty-string-make-sense-...

3) я попробовал вставить предложенную строчку, и убрать свой вывод, но что-то пошло не так...

Если я пишу между кавычками пробел <xsl:output method="html" doctype-system=" " />, то строка DOCTYPE выводится, но пишется про Quirks mode.

А если я не пишу между кавычками пробел <xsl:output method="html" doctype-system="" />, то строка DOCTYPE просто не выводится (и логично, что в результате пишется про Quirks mode).

Вот мой пруф:

<!DOCTYPE html>
<html>
<body onload="onload();">

<script id="xsl" language="application/xslt">
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

        <xsl:output method="html" doctype-system="" />

	<xsl:template match="/">
		<html><head><title>title from XSL</title></head>
		<body>
			Article - <xsl:value-of select="/Article/Title"/>
			<br />
			Authors: <xsl:apply-templates select="/Article/Authors/Author"/>
		</body>
		</html>
	</xsl:template>
	<xsl:template match="Author">
		- <xsl:value-of select="." />
	</xsl:template>
</xsl:stylesheet>
</script>

<script id="xml" language="application/xml">
<?xml version="1.0" encoding="utf-8"?>
<Article>
  <Title>My Article</Title>
  <Authors>
    <Author>Mr. Foo</Author>
    <Author>Mr. Bar</Author>
  </Authors>
  <Body>This is my article text.</Body>
</Article>
</script>

<script language="javascript">
    function onload() {
        // Load XLS
        var xsl_source = document.getElementById("xsl").textContent;
	var xslParser = new DOMParser();
	var xsl_doc = xslParser.parseFromString(xsl_source.trimStart(), "text/xml")
	xsltProcessor = new XSLTProcessor();
        xsltProcessor.importStylesheet(xsl_doc);

        // Load XML 
        var xml_source = document.getElementById("xml").textContent; 
	var xmlParser = new DOMParser();
        var xml_doc = xmlParser.parseFromString(xml_source.trimStart(), "application/xml");

        // Transform
	var htmldoc = xsltProcessor.transformToDocument( xml_doc );
	var html = new XMLSerializer().serializeToString( htmldoc );
	var text = "<html><body><pre><xmp>" + html + "</xmp></pre></body></html>";

	// Update page
	document.write(text);
    }
</script>

</body>
</html>

Shushundr ★★★
() автор топика
Последнее исправление: Shushundr (всего исправлений: 2)
Ответ на: комментарий от static_lab

Способ проверки режима Quirks мне понравился.

Однако я не согласен с тем, что рендер xml через xslt у меня делается по-умолчанию. У меня он делается при помощи javascript. Поэтому DOCTYPE там не указан, сам не возникает.

Shushundr ★★★
() автор топика
Ответ на: комментарий от Anoxemian

Вот это всё-таки заработало:
doctype-system=«about:legacy-compat»

и это нормально, так можно:
https://stackoverflow.com/questions/33575887/in-html5-can-my-doctype-html-dec...

То ли с апдейтом firefox, то ли ранее руки были кривые. Даунгрейдить, чтобы проверить, я уже конечно не буду...
(а то вдруг всё-таки руки, будет обидно и время потеряно)

Финальный вариант, на память:

<!DOCTYPE html><html><body onload="onload();">

<script id="xml" language="application/xml">
<?xml version="1.0" encoding="utf-8"?>
<MyXmlRoot>
</MyXmlRoot>
</script>

<script id="xsl" language="application/xslt">
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:output method="html" doctype-system="about:legacy-compat" />

	<xsl:template match="/">
		<html><head><title>Main content of the page</title></head>
		<body>
			TODO: body for transformed XML
			<div style="background-color: red; width: 100">Should be 100% width in Standards mode and 100px in Quirks mode.</div>
		</body>
		</html>
	</xsl:template>
</xsl:stylesheet>
</script>

<script language="javascript">
    function onload() {
        // Load XLS
        var xsl_source = document.getElementById("xsl").textContent;
	var xsl_doc = new DOMParser().parseFromString(xsl_source.trimStart(), "text/xml")
	xsltProcessor = new XSLTProcessor();
        xsltProcessor.importStylesheet(xsl_doc);

        // Load XML 
        var xml_source = document.getElementById("xml").textContent; 
        var xml_doc = new DOMParser().parseFromString(xml_source.trimStart(), "application/xml");

        // Transform
	var html_doc = xsltProcessor.transformToDocument( xml_doc );
	var html = new XMLSerializer().serializeToString( html_doc );

	// Update page
	document.write(html);
    }
</script>

</body></html>

Shushundr ★★★
() автор топика
Последнее исправление: Shushundr (всего исправлений: 3)