Явный конечный тег скрипта всегда преобразуется в самозакрывающийся - PullRequest
10 голосов
/ 03 декабря 2008

Я использую 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 type="text/javascript" src="jquery-1.2.6.js">
            // <![CDATA[ // ]]>
        </script>

Я думал, что <xsl:output method="html" /> справится, но, похоже, не сработает?

/ Jonas

Ответы [ 11 ]

7 голосов
/ 03 февраля 2009

Если вы создаете 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();
4 голосов
/ 11 января 2009

Это довольно распространенная проблема при генерации HTML из XSLT. Я подозреваю, что корень проблемы в том, что сам XSLT является документом XML. Несмотря на то, что вы запускаете свою программу XSLT в виде сериализованного XML, к тому времени, когда процессор XSLT ее получает, она уже десериализована в представление «infoset». На уровне XML пустой тег и закрытый тег эквивалентны; элемент просто не имеет детей. Это означает, что ваш XSLT-процессор, вероятно, никогда не увидит версию программы, в которой элемент script имеет открывающий и закрывающий теги.

Я обычно обхожу это, используя подходящее место для пробоя. В любом случае, вы должны поместить что-то внутри тега script.

Кстати, дело не в том, чтобы сделать IE счастливым. Если вы посмотрите на HTML spec , вы обнаружите, что конечный тег необходим. Я уверен, что некоторые люди сочтут это ироничным, что IE реализует это правильно. : -)

3 голосов
/ 20 июля 2011

Я нашел этот ответ на сайте форума MSDN:

<xsl:value-of select="' '"/>

Если вы добавите вышеуказанный код xslt до конца вашего кода в файле xsl, он заставит элемент иметь некоторый контент (в данном случае пробел) вместо того, чтобы самозакрываться. Попробовал и все заработало.

Вот что он создал:

<script...> </script>

вместо

<script ... />.
1 голос
/ 21 июня 2011

рассмотрим этот пример,

<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 как (если скидка> 0),

<Discount/>
1 голос
/ 10 марта 2011

Ответ Барт Ван Делфтс указал мне правильное направление с этим, так что поболеть за подсказку!

У меня также была эта проблема с использованием [ javax.xml.transform.Transformer ] Всякий раз, когда я пытался проанализировать фрагмент отформатированного html, в моем случае: -

<textarea></textarea>

окончательный вывод узла был перенесён в мой jsp как: -

<textarea/>

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

установка t.setOutputProperty(javax.xml.transform.OutputKeys.METHOD, "html");, по-видимому, обеспечила поведение самозакрытия, которое я ожидал. Это свойство по умолчанию равно «xml» из моего собственного тестирования, поэтому очевидно, что тег xml без узлов под ним совершенно счастлив как самозакрывающийся.

Надеюсь, это все равно поможет.

1 голос
/ 04 апреля 2010

Это намеренно, и единственный обходной путь, о котором я знаю, - это использовать пользовательский 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();
        }
    }
}
0 голосов
/ 04 мая 2015

Еще один быстрый способ - добавить комментарий Javascript в тег:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">//</script>

Это просто добавит комментарий в конец скрипта - будьте осторожны, что вы ничего не закомментируете по ошибке!

0 голосов
/ 07 декабря 2013

Как уже упоминалось, есть приемы с размещением в элементе невидимого содержимого, но в xslt вы всегда можете отобразить точный вывод в виде текста:

<xsl:text disable-output-escaping="yes">
    &lt;script src="jquery-2.0.3.js"&gt;&lt;/script&gt;
</xsl:text>

Btw. Я думаю, что method = "html" тоже должен помочь, но вы не будете отображать xhtml таким образом, например. br не будет закрыт.

0 голосов
/ 20 июля 2010

Для тех из вас, кто использует 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 включена) не разрешено публиковать более 1 URL: -p

0 голосов
/ 09 февраля 2010

Я использовал комментарий перед тегом конца скрипта, чтобы пройти через эту проблему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...