Сортировка атрибутов в определенном порядке для вывода - PullRequest
4 голосов
/ 18 февраля 2010

Как вы пишете атрибуты элемента в определенном порядке, не записывая это явно?

Рассмотрим:

<xsl:template match="Element/@1|@2|@3|@4">
    <xsl:if test="string(.)">
        <span>
            <xsl:value-of select="."/><br/>
        </span>
    </xsl:if>
</xsl:template>

Атрибуты должны появляться в порядке 1, 2, 3, 4. К сожалению, вы не можете гарантировать порядок атрибутов в XML, это может быть <Element 2="2" 4="4" 3="3" 1="1">

Таким образом, шаблон выше выдаст следующее:

<span>2</span>
<span>4</span>
<span>3</span>
<span>1</span>

В идеале я не хочу проверять каждый атрибут, если он имеет значение. Мне было интересно, могу ли я как-то установить порядок своего дисплея? Или мне нужно будет сделать это явно и повторить тест if, как в:

<xsl:template match="Element">

    <xsl:if test="string(./@1)>
        <span>
            <xsl:value-of select="./@1"/><br/>
        </span>
    </xsl:if>
    ...
    <xsl:if test="string(./@4)>
        <span>
            <xsl:value-of select="./@4"/><br/>
        </span>
    </xsl:if>
</xsl:template>

Что можно сделать в этом случае?

Ответы [ 3 ]

6 голосов
/ 18 февраля 2010

В предыдущем вопросе вы, похоже, использовали XSLT 2.0, поэтому я надеюсь, что на этот раз также возможно решение XSLT 2.0.

Порядок не определяется в шаблоне совпадения шаблона, скорее он определяется при выполнении xsl: apply-templates. Таким образом (с XSLT 2.0) вы можете просто написать последовательность атрибутов в том порядке, в котором вы хотите, например. <xsl:apply-templates select="@att2, @att1, @att3"/> обработает атрибуты в этом порядке.

XSLT 1.0 не имеет последовательностей, только наборы узлов. Чтобы получить тот же результат, используйте xsl:apply-templates в требуемом порядке, например:

<xsl:apply-templates select="@att2"/>
<xsl:apply-templates select="@att1"/>
<xsl:apply-templates select="@att3"/>
3 голосов
/ 18 февраля 2010

Не создавайте XML, который зависит от порядка атрибутов.Это очень хрупко, и я бы сказал, что это плохой стиль, если не сказать больше.XML не был разработан таким образом;<elem a="1" b="2" /> и <elem a="1" b="2" /> явно эквивалентны.

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

Кроме того, match="Element/@1|@2|@3|@4" не эквивалентноmatch="Element/@1|Element/@2|Element/@3|Element/@4", но я уверен, что вы имеете в виду последнее.

С учетом сказанного вы можете сделать:

<xsl:template match="Element/@1|Element/@2|Element/@3|Element/@4">
  <xsl:if test="string(.)">
    <span>
      <xsl:value-of select="."/><br/>
    </span>
  </xsl:if>
</xsl:template>

<xsl:template match="Element">
  <xsl:apply-templates select="@1|@2|@3|@4">
    <!-- order your output... -->
    <xsl:sort select="name()" />
  </xsl:apply-templates>
</xsl:template>

РЕДАКТИРОВАТЬ: я возьму это как прочитанное, что @1и т.д. являются лишь примерами, потому что имена не могут начинаться с цифры в XML.

1 голос
/ 18 февраля 2010

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

<xsl:stylesheet version="1.1" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:template match="Element">
      <xsl:apply-templates select="@*" mode="sorted">
        <xsl:sort select="local-name()" />
    </xsl:apply-templates>
  </xsl:template>

  <xsl:template match="Element/@a|@b|@c|@d" mode="sorted">
    <xsl:if test="string(.)">
        <span>
            <xsl:value-of select="."/><br/>
        </span>
    </xsl:if>
  </xsl:template>
</xsl:stylesheet>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...