Как ссылаться на узел с помощью ключа - XSLT

Учитывая следующий документ XML...

   <ws>
       <series year="2005" mvp="Jermaine Dye">
          <team name="Chicago White Sox" wins="4" />
          <team name="Houston Astros" wins="0" />
       </series>
       <series year="2004" mvp="Manny Ramirez">
          <team name="Boston Red Sox" wins="4" />
          <team name="St. Louis Cardinals" wins="0" />
       </series>
    </ws>

Я создал ключ для получения атрибута имени первой команды в каждой серии, и я пытаюсь просмотреть и перечислить каждое имя для каждой серии следующим образом; В настоящее время я не возвращаю никаких результатов и не уверен, что не так с моей оценкой?...

<xsl:key name="winners" match="team[1]" use="@name" />

    <xsl:template match="/">
        <xsl:for-each select="ws/series">
             <xsl:value-of select="key('winners', @name)" />
        </xsl:for-each>
    </xsl:template>

Ожидаемый результат будет...

Chicago White Sox (the first team from series 1)
Boston Red Sox (the first team from series 2)

Предоставленные мною данные xml включают в себя только 2 элемента серии, когда на самом деле их сотни. Ключ используется для ускорения процесса преобразования и работает вместе с другими ключами для генерации моего результирующего документа.

2 ответа

Решение

Я пытаюсь перечислить название первой команды в каждой серии

Использование ключа является ненужным усложнением для такой простой задачи. Попробуйте просто:

<xsl:template match="/">
    <xsl:for-each select="ws/series">
        <xsl:value-of select="team[1]/@name" />
    </xsl:for-each>
</xsl:template>

Конечно, вы захотите добавить какую-нибудь оболочку или разделитель, иначе вы просто получите путаницу всех имен - скажем (при условии, что метод вывода - это текст):

<xsl:template match="/">
    <xsl:for-each select="ws/series">
        <xsl:value-of select="team[1]/@name" />
        <xsl:if test="position()!=last()">
            <xsl:text>&#10;</xsl:text>
        </xsl:if>
    </xsl:for-each>
</xsl:template>

РЕДАКТИРОВАТЬ:

Чтобы сделать это (искусственно) с помощью ключа, вы должны спросить себя, что связывает команду с ее сериалом (кроме того, что он ребенок). Ответ здесь "ничего". Однако команда имеет доступ к данным своих родительских серий. Поэтому мы могли бы идентифицировать команду по некоторому атрибуту родительского ряда, например по году или MVP. MVP может быть не уникальным для серии, поэтому давайте сделаем ключ:

<xsl:key name="team-by-year" match="team" use="parent::series/@year" />

Это говорит: если вы скажете мне год, я скажу вам команды, которые играли в серии этого года. Итак, отсюда, это просто вопрос вызова ключа текущего года серии:

<xsl:template match="/">
    <xsl:for-each select="ws/series">
        <xsl:value-of select="key('team-by-year', @year)[1]/@name" />
        <xsl:if test="position()!=last()">
            <xsl:text>&#10;</xsl:text>
        </xsl:if>
    </xsl:for-each>
</xsl:template>

Если вы используете это

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

    <xsl:key name="winners" match="team[1]" use="@name" />

    <xsl:template match="/">
        <xsl:for-each select="ws/series/*">
            <xsl:value-of select="key('winners', @name)/@name" />
        </xsl:for-each>
    </xsl:template>

</xsl:stylesheet>
Другие вопросы по тегам