Как сохранить пустые теги XML после XSLT - не допускать их сворачивания с <B></B> до <B /> - PullRequest
12 голосов
/ 11 июня 2009

Скажем, у меня есть очень простой XML с пустым тегом 'B':

<Root>
  <A>foo</A>
  <B></B>
  <C>bar</C>
</Root>

В настоящее время я использую XSLT для удаления нескольких тегов, таких как 'C', например:

<?xml version="1.0" ?>

<xsl:stylesheet version="2.0" xmlns="http://www.w3.org/1999/XSL/Transform" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output method="xml" indent="no" encoding="utf-8" omit-xml-declaration="yes" />

<xsl:template match="*">
    <xsl:copy>
        <xsl:copy-of select="@*" />
        <xsl:apply-templates />
    </xsl:copy>
</xsl:template>

<xsl:template match="C" />

</xsl:stylesheet>

Пока все в порядке, но проблема в том, что я получаю такой вывод:

<Root>
  <A>foo</A>
  <B/>
</Root>

когда я на самом деле очень хочу:

<Root>
  <A>foo</A>
  <B></B>
</Root>

Есть ли способ предотвратить разрушение 'B'?

Спасибо.

Ответы [ 11 ]

9 голосов
/ 11 июня 2009

Хорошо, вот что у меня сработало:

<xsl:output method="html">
3 голосов
/ 01 июня 2011

Попробуйте это:

<script type="..." src="...">&#160;</script>

Ваш вывод HTML будет:

<script type="..." src="..."> </script>

&#160; предотвращает свертывание, но переводит в пустое пространство. Это работало для меня в прошлом.

2 голосов
/ 11 июня 2009

Решение о том, как отображать тег XML, зависит от механизма XSLT, потому что синтаксический анализатор не должен видеть различий между этими двумя вариантами. Однако при выводе HTML это обычная проблема (например, для тегов <textarea> и <script>). Самое простое (но некрасивое) решение - добавить один пробел внутри тега (это немного меняет значение тега хотя.)

2 голосов
/ 11 июня 2009

Стандартного способа не существует, так как они эквивалентны; Возможно, вам удастся найти движок XSLT, у которого есть опция для этого поведения, но я не знаю ни одного.

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

1 голос
/ 14 сентября 2011

Также должен быть другой метод (только XSLT2?): "Xhtml" ( см. Другой поток ). Это предотвращает свертывание тегов и не удаляет закрывающие теги из таких элементов, как .

1 голос
/ 10 января 2011

Они НЕ всегда эквивалентны. Многие браузеры не могут работать с и хотят отдельный закрывающий тег. Я столкнулся с этой проблемой при использовании xml / xsl с PHP. Вывод «html» не работает, я все еще ищу решение.

1 голос
/ 18 октября 2010

Это была давняя проблема, и я наконец заставил ее работать с простым решением. Добавьте , если у вас есть пробел. Я добавил пробел в своем классе помощника. </ XSL: когда> </ XSL: в противном случае> </ XSL: выберите>

0 голосов
/ 26 июля 2016

Уже на 7 лет позже, но для будущих читателей я остановлю эту тенденцию здесь и предложу реальное решение исходного вопроса. Решение, которое не изменяет оригинал пробелами или директивой output.

Идея заключалась в том, чтобы использовать пустую переменную для обмана парсера.

Если вы хотите сделать это только для одного тега B, моей первой мыслью было использовать что-то подобное для присоединения фиктивной переменной.

<xsl:variable name="dummyempty" select="''"/>

<xsl:template match="B">    
  <xsl:copy>
    <xsl:apply-templates select="@*" />
    <xsl:value-of select="concat(., $dummyempty)"/>
  </xsl:copy>    
</xsl:template>

Но я обнаружил, что на самом деле даже фиктивная переменная не нужна. Это сохранило пустые теги, по крайней мере, при тестировании с xsltproc в Linux:

<xsl:template match="B">
  <xsl:copy>
    <xsl:apply-templates select="@*" />
    <xsl:value-of select="."/>
  </xsl:copy>    
</xsl:template>

Для более общего решения для обработки ВСЕХ пустых тегов, попробуйте это:

  <xsl:variable name="dummyempty" select="''"/>

  <xsl:template match="*[. = '']">
    <xsl:copy>
        <xsl:apply-templates select="node()|@*" />
        <xsl:value-of select="$dummyempty"/>
    </xsl:copy>
  </xsl:template>

Опять же, в зависимости от того, насколько умен ваш парсер, вам может даже не понадобиться фиктивная переменная.

0 голосов
/ 25 августа 2009
<xsl:text disable-output-escaping="yes">
<![CDATA[<div></div>]]>
</xsl:text>

Это прекрасно работает с классом XslCompiledTransform в C # с .Net 2.0, но вполне может дать сбой почти везде. Не используйте, если вы программно не выполняете преобразование самостоятельно; это вообще не портативно.

0 голосов
/ 11 июня 2009

Это не должно быть проблемой, если это или . Однако, если вы используете другой инструмент, который ожидает пустые теги XML только как , у вас есть проблема. Не очень элегантный способ сделать это - добавить пробел между начальными и конечными тегами «B» с помощью кода XSLT.

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