Как вы можете иметь дело со встроенными тегами XML в XSLT? - PullRequest
13 голосов
/ 16 января 2011

Я использую 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>

Ответы [ 4 ]

11 голосов
/ 17 января 2011

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

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

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

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

Так вот, как вы получите отчетный результат.

Решение

Используйте инструкцию <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 голосов
/ 18 июня 2012

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

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

'отключение-выход-экранирование' необязательно.«да» означает, что специальные символы (например, «<») должны выводиться как есть.«нет» означает, что специальные символы (например, «<») должны выводиться как «<».По умолчанию «нет». </p>

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

<xsl:template match="favoriteMovie">
  <xsl:copy-of select="node()" disable-output-escaping="yes"/>
</xsl:template>
2 голосов
/ 16 января 2011

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

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>
0 голосов
/ 16 января 2011

Две вещи на заметку.

Во-первых. Убедитесь, что теги экранированы в 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>

РЕДАКТИРОВАТЬ: справился с редактором, теперь код отображается так, как должен

EDIT2: внесены изменения в ваш код

РЕДАКТИРОВАТЬ3: Для кого это может касаться, сама область рассматриваемой проблемы заключается в структурировании информации о фильмах, а не HTML-данных. HTML существует только для целей разметки. Представьте себе, скажем, тег html title внутри FavoritesMovie, тогда как заголовок с таким же именем может быть допустимым тегом в базе данных movies . Эти заголовки ЯВНО должны интерпретироваться по-разному. Это оправдывает использование CDATA, а затем отключает вывод при обработке.

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