用于聊天日志的 XSLT:仅在该值的第一个实例上显示节点值?

发布于 2024-10-26 19:06:57 字数 1808 浏览 1 评论 0原文

我正在将 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>

I'm applying an XSLT stylesheet to an XML chat log and want to only display the chatter's name the first time it appears in consecutive groups of messages, so that multiple lines are "grouped" by chatter in each message group. An example illustrates this better.

I want to go from this:

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

To this:

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

My XSL (which is iterated once per chat line) is this:

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

Can someone help me convert that pseudocode? Thanks so much!

Edit: the input XML is essentially a repetition of the following to/from message structure:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

浸婚纱 2024-11-02 19:06:57

防止同一用户的连续消息显示名称的最简单方法是检查 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>
</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>

The easiest way to prevent the name from showing for consecutive messages from the same user is to check the preceding-sibling axis. The following stylesheet:

<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>
</xsl:text>
        </xsl:if>
        <xsl:value-of select="Text" />
    </xsl:template>
</xsl:stylesheet>

Applied to the following input:

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

Produces the following output:

chatter1
hey
message two
chatter2
hey you!
chatter1
hey

Edit: I would probably handle each case in its own template, like this:

<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>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文