Pergunta

Eu sei que eu estou faltando alguma coisa aqui. Na transformação XSLT a seguir, o resultado real não corresponde ao resultado desejado.

Dentro do for-each, quero aplicar o modelo match="track" a cada elemento track selecionado. Se eu entendi XSLT corretamente, com a configuração atual apenas nós filho de cada elemento track selecionado são comparados com modelos, não os próprios elementos track.

Como posso fazer os elementos track percorrer o modelo como desejar? Eu preciso repensar toda a minha abordagem?

Nota: A transformação é executado usando PHP. declarações XML foram omitidos por brevidade.

documento XML:

<album>
    <title>Grave Dancers Union</title>
    <track id="shove">Somebody To Shove</track>
    <track id="gold">Black Gold</track>
    <track id="train">Runaway Train</track>
    <producer>Michael Beinhorn</producer>
</album>

folha de estilo XSL:

<xsl:stylesheet version="1.1" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/album">
        <ol>
            <xsl:for-each select="track">
                <li><xsl:apply-templates/></li>
            </xsl:for-each>
        </ol>
    </xsl:template>

    <xsl:template match="track">
        <a href="{@id}"><xsl:apply-templates/></a>
    </xsl:template>
</xsl:stylesheet>

Resultado:

<ol>
    <li>Somebody To Shove</li>
    <li>Black Gold</li>
    <li>Runaway Train</li>
</ol>

Resultado pretendido:

<ol>
    <li><a href="shove">Somebody To Shove</a></li>
    <li><a href="gold">Black Gold</a></li>
    <li><a href="train">Runaway Train</a></li>
</ol>
Foi útil?

Solução

Eu concordo com 'ndim' que você provavelmente deve reestruturar seu XSLT para acabar com o xsl:. Para-cada loop

Como alternativa, você pode alterar o xsl: apply-templates para selecionar o nó faixa atual dentro do xsl: for-each

<xsl:for-each select="track">
   <li>
      <xsl:apply-templates select="." />
   </li>
</xsl:for-each>

Mantendo o xsl:. For-each seria, pelo menos, permitir que você classifique as faixas em outra ordem, se desejado

Outras dicas

Eu tinha reestruturar-lo um pouco (se você não precisa a classificar a abordagem for-each torna possível):

<xsl:template match="/album">
  <ol>
    <xsl:apply-templates select="track"/>
  </ol>
</xsl:template>

<xsl:template match="track">
  <li><a href="{@id}"><xsl:apply-templates/></a></li>
<xsl:template>

Isso parece mais curto e mais direto ao ponto, IMHO.

Eu acho que a sua

    <xsl:for-each select="track">
       <li><xsl:apply-templates/></li>
    </xsl:for-each>

caminha por todos os elementos de pista com a for-each, e, em seguida, aplica-se as regras padrão para seus descendentes. Assim, o conteúdo do for-each possui o mesmo nó de contexto como o modelo match="track" possui, e, portanto, o modelo match="track" não corresponde. |

Se você realmente quiser usar o for-each dessa maneira, você vai precisar alterar qualquer uma das duas coisas seguintes na sua abordagem:

  1. Adicionar um atributo name="track" ao modelo match="track", e depois usar <xsl:call-template/> de dentro do for-each (minha idéia, e pior do que Tim C de)
  2. A solução de Uso Tim C usando <xsl:apply-templates select="."/>. Isto tem a vantagem de evitar nomeação e mantendo a possibilidade de ordenar as faixas.

Acho que usando apply-modelos e modos de modelo é a solução mais limpa:

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

  <xsl:template match="/">
    <body>
      <xsl:apply-templates select="album" mode="ol" />
    </body>
  </xsl:template>

  <xsl:template match="album" mode="ol">
    <ol>
      <xsl:apply-templates select="track" mode="li" />
    </ol>
  </xsl:template>

  <xsl:template match="track" mode="li">
    <li>
      <xsl:apply-templates select="." />
    </li>
  </xsl:template>

  <xsl:template match="track">
    <a href="{@id}">
      <xsl:value-of select="." />
    </a>
  </xsl:template>


</xsl:stylesheet>

resulta em:

<body>
  <ol>
    <li>
      <a href="shove">Somebody To Shove</a>
    </li>
    <li>
      <a href="gold">Black Gold</a>
    </li>
    <li>
      <a href="train">Runaway Train</a>
    </li>
  </ol>
</body>

A for-each instrução altera o nó contexto de álbum para acompanhar. A chamada apply-templates por padrão se aplica modelos para os nós filhos do nó de contexto que no seu caso são os nós filhos do elemento de pista. Daí o seu modelo que combina 'faixa' nunca é atingido.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top