【问题标题】:how to apply condition to xsl key如何将条件应用于 xsl 键
【发布时间】:2023-03-23 23:58:02
【问题描述】:

我正在尝试通过 xslt 显示 xml 数据。 我想显示如下输出

// Description  Level         ActivityName ActivityID
// ===========  ============  ============ =======================
// Main Entry   Start         Main Entry   {00000000-0000-0000-0000-000000000000}
// Hello World  Information   Main Entry   {00000000-0000-0000-0000-000000000000}
// alpha        Start         alpha        {aa5a5b9c-4b24-43af-9f49-32656385e17d}
// Hello world  error         alpha        {aa5a5b9c-4b24-43af-9f49-32656385e17d}
// Hello world  Transfer      alpha        {00000000-0000-0000-0000-000000000000}

描述是应用程序数据文本,级别是子类型名称,活动名称是描述。在级别值开始之前,此活动名称将相同。我必须在活动名称下重复相同的描述值,直到您在级别列中获得另一个开始。

XML

<root>
<E2ETraceEvent>
    <System>
        <SubType Name="Start">0</SubType>
        <Correlation ActivityID="00000000-0000-0000-0000-000000000000" />
    </System>
    <ApplicationData>Main Entry </ApplicationData>
</E2ETraceEvent>
<E2ETraceEvent>
    <System>
        <SubType Name="Information">0</SubType>
        <Correlation ActivityID="00000000-0000-0000-0000-000000000000" />
    </System>
    <ApplicationData>Hello World!</ApplicationData>
</E2ETraceEvent>
<E2ETraceEvent>
    <System>
        <SubType Name="Start">0</SubType>
        <Correlation ActivityID="aa5a5b9c-4b24-43af-9f49-32656385e17d" />
    </System>
    <ApplicationData>alpha </ApplicationData>
</E2ETraceEvent>
<E2ETraceEvent>
    <System >
        <SubType Name="Error">0</SubType>
        <Correlation ActivityID="00000000-0000-0000-0000-000000000000" />
    </System>
    <ApplicationData>Hello World!</ApplicationData>
</E2ETraceEvent>
</root>

XSLT

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
  <xsl:output method="html" indent="no"/>
  <xsl:template match="/">
    <html>
      <body>
        <div>
          <div>
            <table>
              <thead>
                <tr>
                  <th>Description</th>
                  <th>Level</th>
                  <th>Activity Name</th>
                  <th>Activity ID</th>
                </tr>
              </thead>
              <tbody>
                <xsl:for-each select="/E2ETraceEvent">
                  <xsl:variable name="level_key" select="/E2ETraceEvent[contains(key,'kSubtypeName')]/value"/>
                  <xsl:variable name="level">
                    <xsl:value-of select="./SubType/@Name"/>
                  </xsl:variable>
                  <xsl:variable name="activityID">
                    <xsl:value-of select="./Correlation/@ActivityID" />
                  </xsl:variable>
                  <xsl:variable name="description">
                    <xsl:value-of select="./ApplicationData/text()" />
                  </xsl:variable>
                  <tr>
                    <td>
                      <xsl:value-of select="$description"/>
                    </td>
                    <td>
                      <xsl:value-of select="$level"/>
                    </td>
                    <td>
                      <xsl:choose>
                        <xsl:when test="$level = 'Start'">
                          <xsl:value-of select="$description"/>
                        </xsl:when>
                        <xsl:otherwise>
                          <xsl:value-of select="$description" />
                        </xsl:otherwise>
                      </xsl:choose>
                    </td>
                    <td>
                      <xsl:value-of select="$activityID"/>
                    </td>
                  </tr>
                </xsl:for-each>
              </tbody>
            </table>
          </div>
        </div>
      </body>
    </html>
  </xsl:template>
</xsl:stylesheet>

【问题讨论】:

  • 您显示的输出是否与您的输入示例匹配?您的输入中只有 4 个 E2ETraceEvent 元素,但您的输出显示 5 行,我觉得这很混乱。我也不明白你对问题的描述:你说“钥匙”是什么意思?您的标题是“XSL 密钥”,但您没有使用xsl:key 元素或 key() 函数。

标签: xml xslt


【解决方案1】:

我只是在这里猜测,但我认为您想简单地做:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes" version="1.0" encoding="utf-8" indent="yes"/>

<xsl:template match="/root">
    <table border="1">
        <thead>
            <th>Description</th>
            <th>Level</th>
            <th>Activity Name</th>
            <th>Activity ID</th>
        </thead>
        <tbody>
            <xsl:for-each select="E2ETraceEvent">
                <tr>
                    <td><xsl:value-of select="ApplicationData"/></td>
                    <td><xsl:value-of select="System/SubType/@Name"/></td>
                    <td>
                        <!-- description from the last 'Start' - including the current node -->
                        <xsl:value-of select="((. | preceding-sibling::E2ETraceEvent)[System/SubType/@Name='Start'])[last()]/ApplicationData"/>
                    </td>
                    <td><xsl:value-of select="System/Correlation/@ActivityID"/></td>
                </tr>
            </xsl:for-each>
        </tbody>
    </table>
</xsl:template>

</xsl:stylesheet>

应用于您的输入示例,这将返回:

【讨论】:

  • 我相信最后一个应该是 Main entry 而不是基于 ActivityId 的 alpha
  • @cilerler 我相信你被一个糟糕的例子误导了。
  • 据我所知,他正试图显示TraceSource 活动日志,所以如果最后一个是 alpha 则没有意义。我相信他想将每个activityIdlevel==start (如果有的话)相关联,并在未来的行中为那些acitivityId 显示activityName(至少这是SvcTraceViewer 的工作方式)
  • @cilerler 我只能通过 OP 对他们要求的描述,而不是你的。如果你觉得你有更好的答案,欢迎发表。我不会改变我的,尤其是。不是在 OP 接受之后。
  • 当然,我只是分享我的想法。如果我能在这里提供更好的答案,可能会迫不及待地发布它:)
猜你喜欢
  • 2011-08-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-13
  • 2019-04-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多