Подтвердить что ты не робот

Как вы можете работать со встроенными тегами XML в XSLT?

Я использую XSLT для преобразования XML в HTML. Мне трудно понять, как обращаться со встроенными XML-узлами для форматирования. Например, допустим, что у меня есть элемент XML:

<favoriteMovie>the <i>Star Wars</i> saga</favoriteMovie>

Однако во время XLST тег <i> игнорируется, поэтому "Звездные войны" не выделяются курсивом в выход HTML. Есть ли относительно простой способ исправить это?

test.xml:

<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="test.html.xsl"?>
<favoriteMovies>
    <favoriteMovie>the <i>Star Wars</i> saga</favoriteMovie>
</favoriteMovies>

test.html.xsl:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="html" omit-xml-declaration="yes" />
    <xsl:template match="/">
      <html>
        <head />
          <body>
            <ul>
                <xsl:for-each select="favoriteMovies/favoriteMovie">
                    <li><xsl:value-of select="." /></li>
                </xsl:for-each>
            </ul>
          </body>
      </html>
    </xsl:template>
</xsl:stylesheet>
4b9b3361

Ответ 1

Однако во время XLST тег <i> получает игнорируется, поэтому "Звездные войны" не курсивом в выводе HTML. Является существует относительно простой способ исправить это?

Ваша проблема здесь:

<ul>
  <xsl:for-each select="favoriteMovies/favoriteMovie">
    <li><xsl:value-of select="."/></li>
  </xsl:for-each>
</ul>

Команда <xsl:value-of> используется для создания текста node. При этом он копирует на выход строковое значение выражения XPath, указанного в атрибуте select этой инструкции XSLT. Строковое значение элемента представляет собой конкатенацию всех его потомков text-node.

Таким образом, вы получаете сообщение о выходе.

Решение

Используйте команду <xsl:copy-of>, которая копирует все узлы, указанные в атрибуте select

<ul>
  <xsl:for-each select="favoriteMovies/favoriteMovie">
    <li><xsl:copy-of select="node()"/></li>
  </xsl:for-each>
</ul>

Другое решение, более связанное с принципами XSLT, позволяет избежать использования <xsl:for-each> вообще:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="/">
  <html>
    <head />
    <body>
     <xsl:apply-templates/>
    </body>
  </html>
 </xsl:template>

 <xsl:template match="/*">
  <ul>
   <xsl:apply-templates/>
  </ul>
 </xsl:template>

 <xsl:template match="favoriteMovie">
  <li><xsl:copy-of select="node()"/></li>
 </xsl:template>
</xsl:stylesheet>

Если любое из двух решений, определенных выше, применяется к предоставленному XML-документу:

<favoriteMovies>
    <favoriteMovie>the 
        <i>Star Wars</i> saga
    </favoriteMovie>
</favoriteMovies>

требуется, правильный результат получается:

<html>
    <head/>
    <body>
        <ul>
            <li>the 
                <i>Star Wars</i> saga
            </li>
        </ul>
    </body>
</html>

Ответ 2

Вы должны использовать xsl: copy для копирования я node.

http://msdn.microsoft.com/en-us/library/ms256128.aspx

    <?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="html" omit-xml-declaration="yes" />
    <xsl:template match="/">
      <html>
        <head />
          <body>
            <xsl:apply-templates></xsl:apply-templates>        
          </body>
      </html>
    </xsl:template>
<xsl:template match="favoriteMovies">
  <ul>
    <xsl:apply-templates></xsl:apply-templates>
  </ul>  
</xsl:template>
  <xsl:template match="favoriteMovie">
    <li>      
      <xsl:apply-templates></xsl:apply-templates>
    </li>
  </xsl:template>
  <xsl:template match="i">
    <xsl:copy>
      <xsl:apply-templates/>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

Ответ 3

Вам следует использовать атрибут "disable-output-escaping". Общий формат элемента:

<xsl:value-of select="expression" disable-output-escaping="yes|no" />

'disable-output-escaping' не является обязательным. "yes" указывает, что специальные символы (например, "<" ) должны выводиться как есть. "no" указывает, что специальные символы (например, "<" ) должны выводиться как "<" . По умолчанию "нет".

Поэтому просто измените свой код на:

<xsl:template match="favoriteMovie">
  <xsl:copy-of select="node()" disable-output-escaping="yes"/>
</xsl:template>

Ответ 4

Следует отметить две вещи.

Во-первых. Убедитесь, что теги экранированы в CDATA

<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="test.html.xsl"?>
<favoriteMovies>
    <favoriteMovie><![CDATA[the <i>Star Wars</i> saga]]></favoriteMovie>
</favoriteMovies>

Во-вторых. Отключить выход:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" omit-xml-declaration="yes" />
<xsl:template match="/">
  <html>
    <head />
      <body>
        <ul>
            <xsl:for-each select="favoriteMovies/favoriteMovie">
                <li><xsl:value-of select="." disable-output-escaping="yes" /></li>
            </xsl:for-each>
        </ul>
      </body>
  </html>
</xsl:template>

EDIT: управлял им с помощью редактора, теперь код отображается как он должен

EDIT2: включены изменения в ваш код

EDIT3: К кому это может относиться, сама область рассматриваемой проблемы связана с структурированием информации о фильмах, а не с данными html. HTML существует только для разметки, представьте себе, что, например, тег заголовка html внутри favoriteMovie, в то время как название тега с названием тега может быть допустимым тегом в базе данных фильмов. Этот заголовок ЧЕТКОГО следует интерпретировать по-разному. Это оправдывает использование CDATA, а затем отключает вывод при обработке.