Pergunta

Eu tenho XML no seguinte formato que quero reformatar:

<blocks>
    <!-- === apples === -->
    <block name="block1">
        ...
    </block>
    <!-- === bananas === -->
    <block name="block2">
        ...
    </block>
    <!-- === oranges === -->
    <block name="block3">
        ...
    </block>
</blocks>

Meu problema é que não consigo descobrir como selecionar os comentários acima de cada tag de bloco. Eu tenho o seguinte XSL:

<xsl:template match="//blocks">
        <xsl:apply-templates select="block" />
</xsl:template>
<xsl:template match="block">
    <xsl:apply-templates select="../comment()[following-sibling::block[@name = ./@name]]" />
    <xsl:value-of select="./@name" />
</xsl:template>
<xsl:template match="comment()[following-sibling::block]">
    <xsl:value-of select="."></xsl:value-of>
</xsl:template>

A saída que estou tentando é:

=== Apples ===
Bloco 1
=== bananas ===
Block2
=== LANGES ===
Bloco3

Mas o melhor que posso obter é:

=== Apples ===
=== bananas ===
=== LANGES ===
Bloco 1
=== Apples ===
=== bananas ===
=== LANGES ===
Block2
=== Apples ===
=== bananas ===
=== LANGES ===
Bloco3

Estou usando o PHP se isso faz alguma diferença.

Foi útil?

Solução

Você pode aplicar os modelos para comentários também nos seus primeiros templos de aplicação em vez do segundo, para que isso aconteça em ordem - também, essa solução depende da ordem dos dados no XML da fonte.

<xsl:template match="//blocks">
        <xsl:apply-templates select="block | comment()" />
</xsl:template>

PS:- Você pode evitar o uso de "//" em suas expressões, pois pode não ser o ideal.

EDITAR Folha de estilo completa

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:template match="//blocks">
  <xsl:apply-templates select="block | comment()"/>
 </xsl:template>
 <xsl:template match="block">
  <xsl:value-of select="./@name"/>
 </xsl:template>
 <xsl:template match="comment()">
  <xsl:value-of select="."/>
 </xsl:template>
</xsl:stylesheet>

Adicione a seguinte instrução Se você deseja linhas de novo, depois de imprimir o valor no bloco e no comentário.

<xsl:text>&#10;</xsl:text>

Outras dicas

Sua folha de estilo é um pouco complicada.

Você deve experimentar a folha de estilo abaixo e descobrirá que ela corresponde à saída que deseja!

<xsl:template match="//blocks">
        <xsl:apply-templates select="block" />
</xsl:template>
<xsl:template match="block">
    <xsl:apply-templates select="preceding-sibling::comment()[1]" />
    <xsl:value-of select="./@name" />
</xsl:template>
<xsl:template match="comment()">
    <xsl:value-of select="."></xsl:value-of>
</xsl:template>

Esse código sempre corresponde a 1 ou 0 comentários que começam logo antes da tag de bloco atual.

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