построение строки XSLT (переменной) в цикле foreach

проблема, с которой я сталкиваюсь, кажется простой, но будучи новичком во всем xsl-код - мне еще предстоит найти правильное решение. То, что я хочу сделать, это построить строку, объединив результаты a foreach Element loop, который я могу позже использовать в качестве значения для атрибута HTML-элемента.

дано:

<?xml version="1.0" encoding="ISO-8859-1"?>
<catalog>
    <cd>
        <country>UK</country>
        <company>CBS Records</company>
    </cd>
    <cd>
        <country>USA</country>
        <company>RCA</company>
    </cd>
    <cd>
        <country>UK</country>
        <company>Virgin records</company>
    </cd>
</catalog>

желаемый результат: CBS;RCA;Virgin records

мне нужна действительная часть XSLT код, который будет выполнять эту трансформация описанным выше способом. Я считаю, что мне нужно на xsl-переменная это будет держать результат конкатенации <company> и разделитель ;. Как это сделать? Спасибо.

3 ответов


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

<xsl:for-each select="catalog/cd">
    <xsl:choose>
        <xsl:when test="position() = 1">
            <xsl:value-of select="country"/>
        </xsl:when>
        <xsl:otherwise>
            ;<xsl:value-of select="country"/>
        </xsl:otherwise>
    </xsl:choose>
</xsl:for-each>

имеет ли это смысл для вас?

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

<xsl:variable name="VariableName">
    <xsl:for-each select="catalog/cd">
        <xsl:choose>
            <xsl:when test="position() = 1">
                <xsl:value-of select="country"/>
            </xsl:when>
            <xsl:otherwise>
                ;<xsl:value-of select="country"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:for-each>
</xsl:variable>

вот одно простое, истинное решение XSLT:

<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="company">
  <xsl:value-of select="."/>
  <xsl:if test="following::company">;</xsl:if>
 </xsl:template>
 <xsl:template match="text()"/>
</xsl:stylesheet>

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

<catalog>
    <cd>
        <country>UK</country>
        <company>CBS Records</company>
    </cd>
    <cd>
        <country>USA</country>
        <company>RCA</company>
    </cd>
    <cd>
        <country>UK</country>
        <company>Virgin records</company>
    </cd>
</catalog>

желаемый, правильный результат (все компании объединены вместе и разделены ;) произведен:

CBS Records;RCA;Virgin records

если вы можете использовать XSLT 2.0, то будет работать любое из следующих действий:

использовать string-join() функция:

<xsl:variable name="companies" select="string-join(catalog/cd/company, ';')" />

использовать @separator С xsl:value-of:

<xsl:variable name="companies" >
   <xsl:value-of select="catalog/cd/company" separator=";" />
</xsl:variable>