Явный script конечный тег всегда преобразуется в самозакрывающийся
Я использую xslt для преобразования xml в aspx файл. В xslt у меня есть тег script, который включает файл jquery.js. Чтобы заставить его работать с IE, тег script должен иметь явный закрывающий тег. По какой-то причине это не работает с xslt ниже.
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
xmlns:asp="remove">
<xsl:output method="html"/>
<xsl:template match="/">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>TEST</title>
<script type="text/javascript" src="jquery-1.2.6.js"></script>
Но если я изменю тег script, как показано ниже, он будет работать.
<script type="text/javascript" src="jquery-1.2.6.js">
// <![CDATA[ // ]]>
</script>
Я думал, что <xsl:output method="html" />
выполнит трюк, но он не работает?
/Jonas
Ответы
Ответ 1
Если вы создаете XmlWriter самостоятельно, вам нужно передать преобразование OutputSettings в XmlWriter, например:
XmlDocument doc = new XmlDocument();
doc.LoadXml("<book><author>Trudi Canavan</author><title>Voice of the Gods</title></book>");
XslCompiledTransform transform = new XslCompiledTransform();
transform.Load("XSLTFile1.xslt");
StringBuilder output = new StringBuilder();
// Here we pass the output setting to the writer, otherwise the transform
// may be set to Html, but the XmlWriter will be outputting Xml
XmlWriter writer = XmlWriter.Create(output, transform.OutputSettings);
transform.Transform(doc, writer);
Console.WriteLine(output.ToString());
Console.ReadKey();
Ответ 2
Это довольно распространенная проблема при создании HTML из XSLT. Я подозреваю, что корень проблемы заключается в том, что сам XSLT является XML-документом. Несмотря на то, что вы начинаете с вашей XSLT-программы в виде сериализованного XML, к тому времени, когда XSLT-процессор получит ее, она уже была де-сериализована для представления "infoset". На уровне XML пустой тег и самозакрывающийся эквивалент; у элемента довольно просто нет детей. Это означает, что ваш XSLT-процессор, вероятно, никогда не увидит версию программы, в которой элемент script имеет как открывающий, так и закрывающий тег.
Я обычно обойдусь этим, используя подходящее экранируемое неразрывное пространство. В любом случае вам нужно положить что-то внутри тега script.
Кстати, речь идет не о том, чтобы сделать IE счастливым. Если вы посмотрите на спецификацию HTML, вы обнаружите, что конечный тег не требуется. Я уверен, что некоторые люди посчитают это ироничным, что IE правильно его реализует.: -)
Ответ 3
Я нашел этот ответ на сайте форума MSDN:
<xsl:value-of select="' '"/>
Если вы добавили вышеуказанный код xslt до конца вашего файла xsl, он заставляет элемент иметь некоторый контент (пробел в этом случае) вместо самозакрывания. Пробовал это, и это сработало.
Это то, что он создал:
<script...> </script>
вместо
<script ... />.
Ответ 4
Это по дизайну, и единственным обходным решением, которое я знаю, является использование пользовательского XmlTextWriter
:
public class HtmlTextWriter : XmlTextWriter
{
private readonly string[] fullEndElements =
new string[] { "script", "title" };
private string lastStartElement = null;
public HtmlTextWriter(TextWriter textWriter)
: base(textWriter)
{
}
public HtmlTextWriter(string filename, Encoding encoding)
: base(filename, encoding)
{
}
public HtmlTextWriter(Stream w, Encoding encoding)
: base(stream, encoding)
{
}
public override void WriteStartElement(string prefix, string localName, string ns)
{
lastStartElement = localName;
base.WriteStartElement(prefix, localName, ns);
}
public override void WriteEndElement()
{
if (Array.IndexOf(fullEndElements, lastStartElement) > -1)
{
base.WriteFullEndElement();
}
else
{
base.WriteEndElement();
}
}
}
Ответ 5
Ответ Барта ван Делфтса указал мне в правильном направлении с этим, так что он приветствует намек!
У меня была и эта проблема, используя [javax.xml.transform.Transformer] Всякий раз, когда я пытался разобрать фрагмент отформатированного html, в моем случае: -
<textarea></textarea>
конечный вывод из Node вносился в мой jsp как: -
<textarea/>
который явно закручивал любой следующий код из-за того, что он рассматривался как больше содержимого элемента textarea.
настройка t.setOutputProperty(javax.xml.transform.OutputKeys.METHOD, "html");
, похоже, обеспечила самозакрывающееся поведение, которое я ожидал. Это свойство по умолчанию является "xml" из моего собственного тестирования, поэтому, очевидно, что тег xml без узлов под ним совершенно счастлив как закрытие себя.
Надеюсь, это все равно поможет.
Ответ 6
рассмотрим этот пример,
<Discount>
<!--<xsl:if test="Discount>0">-->
<xsl:value-of select="Discount"/>
<!--</xsl:if>-->
</Discount>
Если я работаю со скидкой на продукт. и я проверяю его перед использованием. он вернет выход,
<Discount>value of the discount</Discount>
Но если я не комментирую приведенный выше пример,
<Discount>
<xsl:if test="Discount>0">
<xsl:value-of select="Discount"/>
</xsl:if>
</Discount>
он вернет o/p после xslt как (если скидка равнa > 0),
<Discount/>
Ответ 7
И это, конечно, против двигателя MS XSLT? Как странно. Я не могу сказать, что я столкнулся с этим в .NET 1.1 или 2.0, и у меня есть ряд преобразований, которые делают то же самое, поэтому я предлагаю вам пойти с простым обходным путем.
Ответ 8
Я использовал комментарий перед тегом script end, чтобы пройти эту проблему.
Ответ 9
Для тех из вас, кто использует Xalan 2.7.0 (на Java), у меня была та же проблема. Я применил файл org/apache/xml/serializer/ToStream.java в исходном исходном коде, чтобы обойти эту проблему. Если вы укажете как outputProperty:
private static Properties XHTML() {
Properties p = new Properties();
p.setProperty(OutputKeys.METHOD, "xhtml");
p.setProperty(OutputKeys.DOCTYPE_PUBLIC,
"-//W3C//DTD XHTML 1.0 Strict//EN");
p.setProperty(OutputKeys.DOCTYPE_SYSTEM,
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd");
p.setProperty(OutputKeys.ENCODING, "UTF-8");
p.setProperty("{http://xml.apache.org/xalan}indent-amount", "4");
p.setProperty(OutputKeys.INDENT, "yes");
p.setProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
p.setProperty("{http://example.com}selfclosing","no");
return p;
}
Обратите внимание на последнюю строку на selfclosing
. Это свойство, на которое отвечает эта обновленная версия ToStream.java и будет предотвращать теги <div />
и <script />
и выводить теги <div></div>
и <script></script>
. Он также включает в себя исключения из них, а именно те, которые указаны в стандарте HTML, разрешенные для самозакрывания (т.е. "area", "base", "basefont", "br", "col", "frame", "hr" img "," input "," link "," meta "," param"). Это работало для меня, по крайней мере, и теперь веб-страницы отлично отображаются в IE.
Новый файл ToStream.java можно найти в http://bvandelft.ruhosting.nl/ToStream.java и предварительно скомпилированную версию serializer.jar(работа с 2.7) также доступен по одному и тому же URL-адресу, но serializer.jar(в котором включена скомпилированная версия ToStream) не разрешено размещать более одного URL-адреса: -p
Ответ 10
Как уже упоминалось, есть трюки с помещением невидимого содержимого в элемент, но в xslt вы всегда можете отображать точный результат в виде текста:
<xsl:text disable-output-escaping="yes">
<script src="jquery-2.0.3.js"></script>
</xsl:text>
Btw. Я думаю, что метод = "html" тоже должен сделать трюк, но вы не будете отображать xhtml, например, br не будет закрыто.
Ответ 11
Еще один быстрый взлом - добавить комментарий Javascript в тег:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">//</script>
Это просто добавит комментарий в конец script - будьте осторожны, чтобы вы ничего не прокомментировали по ошибке!