xslt объединяет текст из узлов - PullRequest
3 голосов
/ 28 октября 2010

У меня есть XML-файл, который выглядит следующим образом:

<args>
  <sometag value="abc" />
  <anothertag value="def" />
  <atag value="blah" />
</args>

имейте в виду, что имена тегов в аргументах могут быть названы как угодно (я не знаю заранее) Теперь у меня есть этот xml-файл, который хранится в переменной $ data, которую я загрузил с помощью вызова document () в таблице стилей xslt (это не данные для файла xslt)

Я хочу взять эти данные и произвести следующий вывод: sometag = а & anothertag = Защита & ATAG = ли

так (очень упрощенная версия выглядит так:

<xsl:template>
 <xsl:variable name="data"  select="document('/path/to/xml')" />

  <xsl:call-template name='build_string'>
    <xsl:with-param name='data' select='$data' />

  </xsl:call-template>

</xsl:template>

<!-- here is where i need help -->
<xsl:template name="build_string">
  <xsl:param name='data'>
  <xsl:value-of select='name($data/.)' />=<xsl:value-of select='$data/@value' />

  <xsl:if test='$data/following-sibling::node()'>
    <xsl:text>&#38;</xsl:text>
    <xsl:call-template name="build_str">
     <xsl:with-param name="data" select='$nodes/following-sibling::node()' />
    </xsl:call-template>
  </xsl:if>


</xsl:template>

Это почти работает, но также печатает текстовые узлы из входного файла, и я не хочу сопоставлять текстовые узлы ..

Ответы [ 2 ]

14 голосов
/ 28 октября 2010

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

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

 <xsl:template match="/*/*">
  <xsl:value-of select="concat(name(),'=',@value)"/>

  <xsl:if test="not(position()=last())">
    <xsl:text>&amp;</xsl:text>
  </xsl:if>
 </xsl:template>
</xsl:stylesheet>

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

<args>
  <sometag value="abc"/>
  <anothertag value="def"/>
  <atag value="blah"/>
</args>

дает желаемый, правильный результат :

sometag=abc&anothertag=def&atag=blah
3 голосов
/ 28 октября 2010

Я понял, что могу использовать цикл for-each .. Я не уверен, почему я не использовал это для начала. Мне все еще интересно, как я могу рекурсивно перебирать список смежных узлов так, как я это делал раньше (который не работал правильно, потому что он также ловил текстовые узлы и делал другие странные вещи, которые я не мог понять). Вот мое решение (я также добавил переменную-разделитель)

<xsl:template name='string_builder'>
    <xsl:param name='data' />
    <xsl:param name='separator' />        
    <xsl:for-each select='$data/*'>
        <xsl:value-of select='name()'/>=<xsl:value-of select='@value'/>
        <xsl:if test='position() != last()'>
           <xsl:value-of select='$separator'/>
        </xsl:if>
    </xsl:for-each>
</xsl:template>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...