Использование переменной xsl для захвата вывода шаблона вызова, возвращающего пустое значение для меня - PullRequest
8 голосов
/ 14 июня 2011

Я видел много постов, которые делают что-то подобное, и это заставляет меня чувствовать, что это возможно, и я просто делаю что-то не так. Я максимально упростил его, чтобы попытаться выяснить, почему это происходит:

Вот мой xml (ничего особенного):

<?xml version="1.0" encoding="UTF-8"?>
<REPORT>

</REPORT>

Вот мой xsl:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:template match="REPORT">
      <xsl:variable name="tryThisTemplate">
        <xsl:call-template name="TRY_THIS"/>
      </xsl:variable>
      <TEST1>
        <xsl:call-template name="TRY_THIS"/>
      </TEST1>
      <TEST2>
        <xsl:value-of disable-output-escaping="yes" select="$tryThisTemplate" />
      </TEST2>
      <TEST3>
        <xsl:value-of select="$tryThisTemplate" />
      </TEST3>
    </xsl:template>

    <xsl:template name="TRY_THIS">
      <MY_NODE desc="my description" />
    </xsl:template>
</xsl:stylesheet>

Вот мой результат:

<?xml version="1.0" encoding="utf-8"?>  
<TEST1>
  <MY_NODE desc="my description"/>
</TEST1>
<TEST2></TEST2>
<TEST3></TEST3>

Вот мой вопрос: Почему TEST2 и TEST3 не работают? Переменная $ tryThisTemplate выглядит пустой. Я что-то здесь неправильно понимаю. Должен ли я делать это по-другому?

Ответы [ 4 ]

16 голосов
/ 14 июня 2011

Вот правильный способ сделать это (обратите внимание, что DOE не является необходимым и его следует избегать):

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

 <xsl:template match="REPORT">
    <xsl:variable name="tryThisTemplate">
        <xsl:call-template name="TRY_THIS"/>
    </xsl:variable>
    <TEST1>
        <xsl:call-template name="TRY_THIS"/>
    </TEST1>
    <TEST2>
        <xsl:copy-of select="$tryThisTemplate" />
    </TEST2>
    <TEST3>
        <xsl:copy-of select="$tryThisTemplate" />
    </TEST3>
 </xsl:template>

 <xsl:template name="TRY_THIS">
    <MY_NODE desc="my description" />
 </xsl:template>
</xsl:stylesheet>

, когда это преобразование применяется к предоставленномуXML-документ :

<REPORT>

</REPORT>

желаемый результат получен :

<TEST1>
   <MY_NODE desc="my description"/>
</TEST1>
<TEST2>
   <MY_NODE desc="my description"/>
</TEST2>
<TEST3>
   <MY_NODE desc="my description"/>
</TEST3>

Объяснение: <xsl:copy-of> копии (какего название говорит) узлы.<xsl:value-of> выводит строковое значение того, что находится в его атрибуте select.Строковое значение элемента - это объединение (в порядке документа) всех его потомков текстовых узлов.В вашем случае элемент не имеет потомков текстовых узлов и, таким образом, <xsl:value-of> ничего не выводит.

4 голосов
/ 14 июня 2011

Да, здесь есть недоразумение.Если вы пытаетесь скопировать структуру $tryThisTemplate в вывод, вам нужно использовать <xsl:copy-of> вместо <xsl:value-of>.<xsl:value-of> выводит строковое значение своего аргумента select, то есть его текстовое содержимое, которое в данном случае является пустой строкой.

3 голосов
/ 14 июня 2011

Кажется, что переменная $ tryThisTemplate пуста

Переменная не пустая, но с xsl:value-of вы запрашиваете текстовые узлы внутри нее.Это "пусто".

Например, попробуйте:

  <TEST3>
    <xsl:copy-of select="$tryThisTemplate" />
  </TEST3>

И вы увидите магическое появление MY_NODE между TEST3:))

0 голосов
/ 08 января 2017

проверьте мое решение

вот мой шаблон (был проверяемый контент)

<xsl:template name="author-name" match="string-name">
    <xsl:if test="fn[string-length(normalize-space()) > 0] or given-names[string-length(normalize-space()) > 0]">
        <xsl:apply-templates select="fn | given-names" mode="ascii"/>
    </xsl:if>
    <xsl:if test="sn[string-length(normalize-space()) > 0] or surname[string-length(normalize-space()) > 0]">
        <xsl:text> </xsl:text><xsl:apply-templates select="sn | surname" mode="ascii"/>
    </xsl:if>
    <xsl:if test="sn[string-length(normalize-space()) > 0] or suffix[string-length(normalize-space()) > 0]">
        <xsl:text> </xsl:text><xsl:apply-templates select="sn | suffix" mode="ascii"/>
    </xsl:if>
</xsl:template>

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

<xsl:template match="string-name">
    <xsl:variable name="author">
        <xsl:call-template name="author-name"/> <!--here is the tricky part-->
    </xsl:variable>
    <span class="NLM_{name()}">
        <xsl:copy-of select="@id" />
        <xsl:value-of select="normalize-space($author)" />
    </span>   
</xsl:template>

надеюсь, это поможет вам

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