Проблема самозакрывающихся тегов XSLT - PullRequest
23 голосов
/ 20 мая 2009

Я использую xslt для преобразования XML-файла в HTML. Движок .net xslt продолжает предоставлять мне самозакрывающиеся теги для пустых тегов.

Пример:

<div class="test"></div> 

становится

<div class="test" />

Первый является действительным html, а второй является недействительным html и плохо отображает. Мой вопрос: Как мне сказать движку xslt (XslCompiledTransform) не использовать самозакрывающиеся теги.

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

Ответы [ 11 ]

23 голосов
/ 20 мая 2009

Измените метод xsl:output на html (вместо xml).

Или добавьте его, если у вас еще нет элемента

<xsl:output method="html"/>
15 голосов
/ 23 января 2012

Обходным путем может быть вставка элемента комментария для принудительной генерации несамостоятельного закрытия:

<script type="text/javascript" src="nowhere.js">
<xsl:comment></xsl:comment>
</script>

Это не очень хорошее решение, но оно работает: -)

/ Sten

11 голосов
/ 20 мая 2009

Если вы используете XmlWriter в качестве потока вывода, используйте взамен HTMLTextWriter. XMLWriter переформатирует ваш HTML-вывод обратно в XML.

4 голосов
/ 15 сентября 2010
3 голосов
/ 24 ноября 2010

Для меня это была проблема в теге script . Я решил это, заполнив его точкой с запятой (; )

<script type="text/javascript" src="somewhere.js">;</script>
2 голосов
/ 19 июля 2011

Я использовал элемент <xsl:text> внутри, как:

<script type="text/javascript" src="/scripts/jquery.js"><xsl:text> </xsl:text></script>
2 голосов
/ 20 мая 2009

Вы не можете сказать своему браузеру обрабатывать недопустимый HTML как HTML - вам повезло, что он вообще понимает некорректный HTML. :)

Определенно сделайте это в вашей таблице стилей:

<xsl:output method="html"/>

Но если ваш исходный документ имеет пространства имен, это не сработает. Процессоры XSLT, по-видимому, молча меняют метод вывода обратно на XML, если в выводе присутствуют узлы пространства имен.

Вам необходимо заменить все экземпляры <xsl:copy-of> и <xsl:copy> на создание элементов только с локальным именем, например,

<xsl:template match="*">
   <xsl:element name="{local-name()}">
     <xsl:apply-templates/>
   </xsl:element>
</xsl:template>

См

и т.д.

1 голос
/ 06 апреля 2014

Есть несколько вещей, которые нужно соблюдать осторожность:

  1. В вашем xsl использовании
  2. установить OutputSettings в ваш вывод XmlWriter
  3. в HTML внутри вашего xsl, не устанавливайте атрибуты в теге html вот так но используйте вместо этого .

Это часть рабочего кода:

string xmlStr = "<?xml version='1.0' encoding='UTF-8'?><Data></Data>";
XmlDocument doc = new XmlDocument();
doc.LoadXml(xmlStr);
string xslContents = @"
<xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'  
xmlns:msxsl='urn:schemas-microsoft-com:xslt' exclude-result-prefixes='msxsl'>
<xsl:output method='html' version='4.0' omit-xml-declaration='yes' indent='yes'/>
<xsl:template match='Data'>
<html>
<body>
    <div></div>
</body>
</html>
</xsl:template>
</xsl:stylesheet>";
XslCompiledTransform xsl = new XslCompiledTransform();
xsl.Load(XmlReader.Create(new StringReader(xslContents)));
StringWriter result = new StringWriter();
using (XmlWriter writer = XmlWriter.Create(result, xsl.OutputSettings))
{
    xsl.Transform(doc, null, writer);
}
System.Diagnostics.Debug.Write( result.ToString());
0 голосов
/ 21 февраля 2018

Простой способ, который я нашел, - это создание нового класса XmlTextWriter для переопределения метода WriteEndElement, принудительного использования незамкнутого тега и передачи процесса сериализации в качестве параметра.

public class MyXmlTextWriter : XmlTextWriter
{
    public MyXmlTextWriter(Stream stream) : base(stream, Encoding.UTF8)
    { }
    public MyXmlTextWriter(TextWriter stream) : base(stream)
    { }

    public override void WriteEndElement()
    {
        base.WriteFullEndElement();
    }
}
0 голосов
/ 02 июля 2014

Я использую следующее всякий раз, когда хочу предотвратить самозакрытие элемента:

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

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

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

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


<div class="test">
   <xsl:call-template name="PreventSelfClosure"/>
</div>

После этого отобразится следующее:

<div class="test"></div>

http://curtistimson.co.uk/post/xslt/how-to-prevent-self-closing-elements-in-xslt/

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