2009-11-06 5 views
2

У меня есть XML в следующем формате, который я хочу, чтобы переформатировать:XSLT/Xpath: Выбор предыдущего комментария

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

Моя проблема, я не могу понять, как выбрать комментарии выше каждого блока метки. У меня есть следующий 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> 

Вывод, который я пытаюсь для это:

=== яблоки ===
block1
=== бананы ===
block2
=== апельсины ===
block3

но лучшее, что я могу получить это:

=== яблоки ===
=== бананы ===
=== апельсины ===
block1
=== яблоки ===
=== бананы ===
=== апельсины ===
block2
=== яблоки ===
=== бананы ===
=== апельсины ===
block3

I A m, используя PHP, если это имеет значение.

ответ

0

Вы можете применить шаблоны для комментариев также в своих первых шаблонах заявок вместо второго, чтобы это произошло в порядке. Также это решение зависит от порядка данных в исходном xml ..

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

PS: - Вы можете избежать использования «//» в своих выражениях, поскольку это может быть неоптимальным.

[EDIT] Полный стилевых

<?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> 

Добавьте следующее заявление, если вы хотите новой строки, после того, как вы печатаете значение как в блоке и комментарии.

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

Спасибо, я предпочитаю вашу версию, которая кажется более простой. Прекрасно работает. –

3

Ваша таблица стилей немного сложна.

Вы должны попробовать таблицу стилей ниже, и вы обнаружите, что она соответствует выходу, который вы хотите!

<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> 

Этот код всегда соответствует 1 или 0 комментариям, начинающимся прямо перед тегом блока.

+0

Спасибо, это работает. Причиной для сложной таблицы стилей является фактический XML, который я использую, и комментарии в других местах тоже, и я стараюсь избегать их сопоставления. –