Использование XSLT для вывода пустого элемента HTML textarea

при попытке вывода пустого элемента textarea процессор .NET XSLT сворачивает элемент в его короткую форму. Вместо этого:

<textarea id="blah" name="blah"></textarea>

Я получаю это:

<textarea id="blah" name="blah"/>

что заставляет многие веб-браузеры (включая IE и Firefox) отображать остальную часть страницы, как если бы это было содержание тега textarea. фтопку.

Я могу заставить процессор XSLT выводить как открывающие, так и закрывающие теги textarea, если я поместите что-то между ними, как неразрывное пространство. Но это означает, что мне нужно сделать больше синтаксического анализа и проверки на стороне клиента, чтобы сказать, когда textarea "действительно" пуст. Я также должен использовать JavaScript для удаления дополнительного пространства, чтобы пользователи не начинали свои комментарии с пустого пространства.

кто-нибудь знает способ заставить процессор XSLT отображать как открывающие, так и закрывающие теги без вставить содержимое пустышка?

6 ответов


найдите свой ответ через аналогичный вопрос прямо здесь on Stackoverflow.com : -)

здесь является дальнейшим объяснением от MSDN.


Я вы должны использовать фиктивный контент, это был шаблон xsl:, который я использовал, имея только символ подачи строки внутри textarea.

<!-- This prevents empty textarea elements being rendered as singletons in the XHTML output by adding a newline character -->
<xsl:template name="xhtml-textarea-contents">
    <!-- what should be contained in the textarea -->
    <xsl:param name="contents" />

    <xsl:choose>
        <xsl:when test="$contents = ''"><xsl:text>&#x0A;</xsl:text></xsl:when>
        <xsl:otherwise><xsl:copy-of select="$contents" /></xsl:otherwise>
    </xsl:choose>
</xsl:template>

У Криса балланса был ответ, который сработал для меня. Но стоит отметить, что я использовал перегрузку XslCompiledTransform, которая выводится в поток, например:

XslCompiledTransform transform = new XslCompiledTransform();
...
MemoryStream stream = new MemoryStream();
transform.Transform(reader, args, stream);

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

// using XmlWriter so I can pass the output settings along.
XmlWriter writer = XmlWriter.Create(stream, transform.OutputSettings);
transform.Transform(reader, args, writer);

Microsoft использует действительно странный шаблон дизайна.


Если вы создаете xml или html, вы можете написать новую строку внутри textarea, а затем удалить ее с помощью jquery.

Это пример с jQuery:

<textarea>&#160;<textarea>

<script>
 $(document).ready(function(){
    $('textarea').each(
      function(index){$(this).text('');}
     );
  });
</script>

я столкнулся с этой проблемой за пределами .net, которая воспроизводима [для меня] в обоих <xsl:output method="xml"> и <xsl:output method="xhtml"> (Я делаю предположение, что method="html" неприменимо к нашему сценарию, где выход должен быть хорошо сформированным xml)

чтобы избежать коллапса тега textarea, мы должны вставить в него некоторое содержимое, но мы также должны избегать подделки фактический содержание. Следующее:

<xsl:if test="not(normalize-space())"><xsl:comment></xsl:comment></xsl:if>

дает правильные результаты (т. е. предотвращает пустые textarea от самозакрывания и не вводит искусственного содержания). Я считаю, что это поведение упоминается в спецификации под построение узла из пост-схемы-проверка infoset, где строковые значения пустых комментариев станут строками нулевой длины; однако формулировка документа waaay слишком w3-ey для легкого дневного чтения.

толкая его немного дальше (поэтому, если он не вмешивается в содержание, нам действительно нужно xsl:if?), это финал шаблон, который предотвращает коллапс определенных тегов (я стремлюсь следовать идентификационными данными, преобразовывают узор):

<xsl:template match="node()|@*">
    <xsl:copy>
        <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="textarea">
    <xsl:copy>
        <xsl:apply-templates select="node()|@*"/>
        <xsl:comment></xsl:comment>
    </xsl:copy>
</xsl:template>

NB: поведение браузеров предполагает, что это преобразование должно применяться и к некоторым другим элементам, таким как абзацы. Имея self-closing <p/>, однако, не так разрушительно, как иметь самозакрывающийся <textarea/>!


У меня была аналогичная проблема и я только что понял, что если вы установите ConformanceLevel XmlWriterSettings на фрагмент, это устраняет некоторые из причуд XslCompiledTransform.

FileStream xmlFileStream = File.Create("file.xml");
XslCompiledTransform transform = new XslCompiledTransform();
transform.Load("transform.xsl");
XmlWriterSettings settings = new XmlWriterSettings();
settings.ConformanceLevel = ConformanceLevel.Fragment;
XmlWriter xmlWriter = XmlWriter.Create(xmlFileStream, settings);
transform.Transform(sourceXml, null, xmlWriter);