XSLT для журналов чата: отображение значения узла только в первом экземпляре этого значения? - PullRequest
1 голос
/ 28 марта 2011

Я применяю таблицу стилей XSLT к журналу чата XML и хочу отображать имя болтовни только в первый раз, когда оно появляется в последовательных группах сообщений, чтобы несколько строк «группировались» по болтовне в каждой группе сообщений.Пример иллюстрирует это лучше.

Я хочу перейти от этого:

<Cthon98> hey, if you type in your pw, it will show as stars
<Cthon98> ********* see!
<AzureDiamond> hunter2
<AzureDiamond> doesnt look like stars to me

К этому:

<Cthon98> hey, if you type in your pw, it will show as stars
          ********* see!
<AzureDiamond> hunter2
               doesnt look like stars to me

Мой XSL (который повторяется один раз для строки чата) это:

<xsl:template match="User">
    <!-- add a comma before all but the first user -->
    <xsl:if test="position() != 1">, </xsl:if>

    <!-- Pseudocode:
        1. Set variable to name of current chatter
        2. Set variable to name of previous line's chatter
        3. If current chatter == previous chatter, don't display name
        4. If current chatter != previous chatter, display name
    -->

    <!-- This displays the name -->
    <xsl:value-of select="@FriendlyName"/>
</xsl:template>

Может ли кто-нибудь помочь мне преобразовать этот псевдокод?Большое спасибо!

Редактировать: входной XML по сути повторяет следующую структуру сообщения:

<?xml version="1.0"?>
<?xml-stylesheet type='text/xsl' href='MessageLog.xsl'?>
<Log FirstSessionID="1" LastSessionID="20">
    <Message>
        <From><User FriendlyName="chatter1"/></From>
        <To><User FriendlyName="chatter2"/></To>
        <Text>hey</Text>
    </Message>
    <Message>
        <From><User FriendlyName="chatter2"/></From>
        <To><User FriendlyName="chatter1"/></To>
        <Text>hey!</Text>
    </Message>
</Log>

1 Ответ

0 голосов
/ 28 марта 2011

Самый простой способ запретить отображение имени для последовательных сообщений от одного и того же пользователя - это проверить ось preceding-sibling. Следующая таблица стилей:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="Message">
        <xsl:if
            test="not(From/User/@FriendlyName = preceding-sibling::Message[1]/From/User/@FriendlyName)">
            <xsl:value-of select="From/User/@FriendlyName" />
            <xsl:text>&#10;</xsl:text>
        </xsl:if>
        <xsl:value-of select="Text" />
    </xsl:template>
</xsl:stylesheet>

Применяется к следующему входу:

<Log FirstSessionID="1" LastSessionID="49">
    <Message>
        <From><User FriendlyName="chatter1"/></From>
        <To><User FriendlyName="chatter2"/></To>
        <Text>hey</Text>
    </Message>
    <Message>
        <From><User FriendlyName="chatter1"/></From>
        <To><User FriendlyName="chatter2"/></To>
        <Text>message two</Text>
    </Message>
    <Message>
        <From><User FriendlyName="chatter2"/></From>
        <To><User FriendlyName="chatter1"/></To>
        <Text>hey you!</Text>
    </Message>
    <Message>
        <From><User FriendlyName="chatter1"/></From>
        <To><User FriendlyName="chatter2"/></To>
        <Text>hey</Text>
    </Message>
</Log>

Создает следующий вывод:

chatter1
hey
message two
chatter2
hey you!
chatter1
hey

Редактировать: Я бы, наверное, обрабатывал каждый случай в своем собственном шаблоне, например:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template
        match="Message[not(From/User/@FriendlyName = preceding-sibling::Message[1]/From/User/@FriendlyName)]">
        <!-- name and text -->
        <xsl:value-of select="From/User/@FriendlyName" />
        <xsl:value-of select="Text" />
    </xsl:template>
    <xsl:template match="Message">
        <!-- text only -->
        <xsl:value-of select="Text" />
    </xsl:template>
</xsl:stylesheet>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...