XSL: вывод «вложенных» структур - PullRequest
2 голосов
/ 17 февраля 2012

У меня есть XML-документ следующего вида:

<item>
  <item>
    <item>
     ... (same elements <item> ... </item> here) 
    </item>
  </item>
</item>

... и следующее XSL-преобразование:

<xsl:template match="item"><xsl:text>
open</xsl:text>
 <xsl:apply-templates/><xsl:text>
close</xsl:text>
</xsl:template>

Что я получаю:

open
open
open
close
close
close

Поэтому мне интересно, можно ли как-нибудь получить вывод с отступами , например так:

open
   open
      open
      close
   close
close

Спасибо за помощь!

PSдолжно быть определенно возможно получить то, что я хочу, позволяя метод вывода преобразования быть HTML.Однако мне нужно делать отступы «прямо» в тексте, не используя какие-либо списки HTML и т. Д.

Ответы [ 3 ]

3 голосов
/ 17 февраля 2012

Это преобразование :

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text"/>

 <xsl:template match="item">
  <xsl:param name="pIndent" select="'  '"/>

  <xsl:value-of select="concat('&#xA;', $pIndent, 'open')"/>

  <xsl:apply-templates>
   <xsl:with-param name="pIndent"
        select="concat($pIndent, '  ')"/>
  </xsl:apply-templates>

  <xsl:value-of select="concat('&#xA;', $pIndent, 'close')"/>
 </xsl:template>

 <xsl:template match="node()[not(self::item)]">
  <xsl:apply-templates/>
 </xsl:template>
</xsl:stylesheet>

при применении к предоставленному документу XML :

<item>
    <item>
        <item>      ...
            <item> ... </item>
        </item>
    </item>
</item>

производит желаемый выход с отступом :

  open
    open
      open
        open
        close
      close
    close
  close

Объяснение

Параметр $pIndent используется для хранения строки пробела, которая должна быть добавлена ​​перед выводом без пробелов. Всякий раз, когда используется xsl:apply-templates, значение, переданное с этим параметром, увеличивается на два пробела.

0 голосов
/ 17 февраля 2012

Существует "чит" способ сделать это, используя подстроку.Чтобы изменить шаблон, который у вас уже есть:

<xsl:template match="item">
  <xsl:variable name="indent" select="substring('          ',1,count(ancestor::*)*2)" />
  <xsl:text>&#10;</xsl:text>
  <xsl:value-of select="$indent" />
  <xsl:text>open</xsl:text>
  <xsl:apply-templates/>
  <xsl:text>&#10;</xsl:text>
  <xsl:value-of select="$indent" />
  <xsl:text>close</xsl:text>
</xsl:template>

Как видите, он просто вставляет количество пробелов в зависимости от того, сколько предков у элемента (умножено на 2), беря часть строкипространств.Я использовал 10 здесь, что означает, что он перестанет отступать на 5 уровнях, но вы можете использовать просто использовать более длинную строку, если ваш XML глубже этого.

Это также имеет то преимущество, что вы можете сделатьПользовательский отступ довольно легко, используя другую строку.Например, вы можете использовать 1-2-3-4-5-6-7-8-9-, если хотите четко показать отступ в каждой строке.

Я также заменил возврат каретки на &#10;, чтобы сделать код проще для отступа для удобства чтения.

0 голосов
/ 17 февраля 2012

Это просто, просто используйте вкладки внутри вас <xsl:text> элементов (я не знаю, как их здесь разместить):

<xsl:template match="item"><xsl:text>
open</xsl:text>

Однако для достижения структуры с отступом вам потребуется создать именованный шаблон или функцию xpath, которая выводит несколько раз табуляцию (или пробелы).

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