在 XSLT 中实现查找
implementing lookup in XSLT
运行 xml and xslt 并在底部获取输出。手动添加 黑色背景 Activity 正确名称 的列以提供所需的输出 Activity 名称 此时产生错误值的列。我想实现以下逻辑。
Pseudo;
- Select records where Level==Start
- Set ActivityName = Description
- Capture ActivityId and ActivityName into memory for future lookup
- Set each record's ActivityName based on Captured records where ActivityId is a match
您还可以在 .NET Fiddle
处找到使用 C# 完成的逻辑
XML
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="test.xsl" ?>
<root>
<E2ETraceEvent xmlns="http://schemas.microsoft.com/2004/06/E2ETraceEvent">
<System xmlns="http://schemas.microsoft.com/2004/06/windows/eventlog/system">
<SubType Name="Information">0</SubType>
<Correlation ActivityID="a54221e2-ad37-434a-8f0d-101f7abc2221" />
</System>
<ApplicationData>Test21</ApplicationData>
</E2ETraceEvent>
<E2ETraceEvent xmlns="http://schemas.microsoft.com/2004/06/E2ETraceEvent">
<System xmlns="http://schemas.microsoft.com/2004/06/windows/eventlog/system">
<SubType Name="Information">0</SubType>
<Correlation ActivityID="d30741c2-da73-434a-8f0d-101f7ceb2228" />
</System>
<ApplicationData>Test24</ApplicationData>
</E2ETraceEvent>
<E2ETraceEvent xmlns="http://schemas.microsoft.com/2004/06/E2ETraceEvent">
<System xmlns="http://schemas.microsoft.com/2004/06/windows/eventlog/system">
<SubType Name="Start">0</SubType>
<Correlation ActivityID="00000000-0000-0000-0000-000000000000" />
</System>
<ApplicationData>Alpha</ApplicationData>
</E2ETraceEvent>
<E2ETraceEvent xmlns="http://schemas.microsoft.com/2004/06/E2ETraceEvent">
<System xmlns="http://schemas.microsoft.com/2004/06/windows/eventlog/system">
<SubType Name="Information">0</SubType>
<Correlation ActivityID="00000000-0000-0000-0000-000000000000" />
</System>
<ApplicationData>Test31</ApplicationData>
</E2ETraceEvent>
<E2ETraceEvent xmlns="http://schemas.microsoft.com/2004/06/E2ETraceEvent">
<System xmlns="http://schemas.microsoft.com/2004/06/windows/eventlog/system">
<SubType Name="Verbose">0</SubType>
<Correlation ActivityID="3b081a36-43d5-4ecc-b381-628c33316205" />
</System>
<ApplicationData>Test51</ApplicationData>
</E2ETraceEvent>
<E2ETraceEvent xmlns="http://schemas.microsoft.com/2004/06/E2ETraceEvent">
<System xmlns="http://schemas.microsoft.com/2004/06/windows/eventlog/system">
<SubType Name="Start">0</SubType>
<Correlation ActivityID="aa5a5b9c-4b24-43af-9f49-32656385e17d" />
</System>
<ApplicationData>Bravo</ApplicationData>
</E2ETraceEvent>
<E2ETraceEvent xmlns="http://schemas.microsoft.com/2004/06/E2ETraceEvent">
<System xmlns="http://schemas.microsoft.com/2004/06/windows/eventlog/system">
<SubType Name="Start">0</SubType>
<Correlation ActivityID="d30741c2-da73-434a-8f0d-101f7ceb2228" />
</System>
<ApplicationData>Charlie</ApplicationData>
</E2ETraceEvent>
<E2ETraceEvent xmlns="http://schemas.microsoft.com/2004/06/E2ETraceEvent">
<System xmlns="http://schemas.microsoft.com/2004/06/windows/eventlog/system">
<SubType Name="Error">0</SubType>
<Correlation ActivityID="aa5a5b9c-4b24-43af-9f49-32656385e17d" />
</System>
<ApplicationData>Test71</ApplicationData>
</E2ETraceEvent>
<E2ETraceEvent xmlns="http://schemas.microsoft.com/2004/06/E2ETraceEvent">
<System xmlns="http://schemas.microsoft.com/2004/06/windows/eventlog/system">
<SubType Name="Transfer">0</SubType>
<Correlation ActivityID="00000000-0000-0000-0000-000000000000" />
</System>
<ApplicationData>Test41</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"
xmlns:te="http://schemas.microsoft.com/2004/06/E2ETraceEvent"
xmlns:s="http://schemas.microsoft.com/2004/06/windows/eventlog/system"
xmlns:sd="http://schemas.microsoft.com/2004/08/System.Diagnostics"
xmlns:tr="http://schemas.microsoft.com/2004/10/E2ETraceEvent/TraceRecord"
exclude-result-prefixes="te s sd tr">
<xsl:output method="html" indent="no"/>
<xsl:template match="/">
<html>
<head>
</head>
<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="//te:E2ETraceEvent">
<xsl:variable name="level">
<xsl:value-of select=".//s:SubType/@Name"/>
</xsl:variable>
<xsl:variable name="description">
<xsl:value-of select=".//te:ApplicationData/text()"/>
</xsl:variable>
<tr>
<!-- APPLICATION DATA -->
<td>
<xsl:value-of select="$description"/>
</td>
<!-- LEVEL -->
<td>
<xsl:value-of select="$level"/>
</td>
<!-- ACTIVITY NAME -->
<td>
<xsl:value-of select="((. | preceding-sibling::te:E2ETraceEvent)[s:System/s:SubType/@Name='Start'])[last()]/te:ApplicationData"/>
</td>
<!-- ACTIVITY ID -->
<td>
<xsl:value-of select=".//s:Correlation/@ActivityID"/>
</td>
</tr>
</xsl:for-each>
</tbody>
</table>
</div>
</div>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
输出
您的伪代码有点神秘(好像没有 Level==Start 的记录)。此外,XSLT 不是那样工作的。在 XSLT 中,查找是使用 key 完成的。
尝试将其添加到样式表的顶层:
<xsl:key name="start" match="te:E2ETraceEvent[s:System/s:SubType/@Name='Start']" use="s:System/s:Correlation/@ActivityID" />
然后将此列添加到您的 table:
<td>
<xsl:value-of select="key('start', s:System/s:Correlation/@ActivityID)/te:ApplicationData"/>
</td>
运行 xml and xslt 并在底部获取输出。手动添加 黑色背景 Activity 正确名称 的列以提供所需的输出 Activity 名称 此时产生错误值的列。我想实现以下逻辑。
Pseudo;
- Select records where Level==Start
- Set ActivityName = Description
- Capture ActivityId and ActivityName into memory for future lookup
- Set each record's ActivityName based on Captured records where ActivityId is a match
您还可以在 .NET Fiddle
处找到使用 C# 完成的逻辑XML
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="test.xsl" ?>
<root>
<E2ETraceEvent xmlns="http://schemas.microsoft.com/2004/06/E2ETraceEvent">
<System xmlns="http://schemas.microsoft.com/2004/06/windows/eventlog/system">
<SubType Name="Information">0</SubType>
<Correlation ActivityID="a54221e2-ad37-434a-8f0d-101f7abc2221" />
</System>
<ApplicationData>Test21</ApplicationData>
</E2ETraceEvent>
<E2ETraceEvent xmlns="http://schemas.microsoft.com/2004/06/E2ETraceEvent">
<System xmlns="http://schemas.microsoft.com/2004/06/windows/eventlog/system">
<SubType Name="Information">0</SubType>
<Correlation ActivityID="d30741c2-da73-434a-8f0d-101f7ceb2228" />
</System>
<ApplicationData>Test24</ApplicationData>
</E2ETraceEvent>
<E2ETraceEvent xmlns="http://schemas.microsoft.com/2004/06/E2ETraceEvent">
<System xmlns="http://schemas.microsoft.com/2004/06/windows/eventlog/system">
<SubType Name="Start">0</SubType>
<Correlation ActivityID="00000000-0000-0000-0000-000000000000" />
</System>
<ApplicationData>Alpha</ApplicationData>
</E2ETraceEvent>
<E2ETraceEvent xmlns="http://schemas.microsoft.com/2004/06/E2ETraceEvent">
<System xmlns="http://schemas.microsoft.com/2004/06/windows/eventlog/system">
<SubType Name="Information">0</SubType>
<Correlation ActivityID="00000000-0000-0000-0000-000000000000" />
</System>
<ApplicationData>Test31</ApplicationData>
</E2ETraceEvent>
<E2ETraceEvent xmlns="http://schemas.microsoft.com/2004/06/E2ETraceEvent">
<System xmlns="http://schemas.microsoft.com/2004/06/windows/eventlog/system">
<SubType Name="Verbose">0</SubType>
<Correlation ActivityID="3b081a36-43d5-4ecc-b381-628c33316205" />
</System>
<ApplicationData>Test51</ApplicationData>
</E2ETraceEvent>
<E2ETraceEvent xmlns="http://schemas.microsoft.com/2004/06/E2ETraceEvent">
<System xmlns="http://schemas.microsoft.com/2004/06/windows/eventlog/system">
<SubType Name="Start">0</SubType>
<Correlation ActivityID="aa5a5b9c-4b24-43af-9f49-32656385e17d" />
</System>
<ApplicationData>Bravo</ApplicationData>
</E2ETraceEvent>
<E2ETraceEvent xmlns="http://schemas.microsoft.com/2004/06/E2ETraceEvent">
<System xmlns="http://schemas.microsoft.com/2004/06/windows/eventlog/system">
<SubType Name="Start">0</SubType>
<Correlation ActivityID="d30741c2-da73-434a-8f0d-101f7ceb2228" />
</System>
<ApplicationData>Charlie</ApplicationData>
</E2ETraceEvent>
<E2ETraceEvent xmlns="http://schemas.microsoft.com/2004/06/E2ETraceEvent">
<System xmlns="http://schemas.microsoft.com/2004/06/windows/eventlog/system">
<SubType Name="Error">0</SubType>
<Correlation ActivityID="aa5a5b9c-4b24-43af-9f49-32656385e17d" />
</System>
<ApplicationData>Test71</ApplicationData>
</E2ETraceEvent>
<E2ETraceEvent xmlns="http://schemas.microsoft.com/2004/06/E2ETraceEvent">
<System xmlns="http://schemas.microsoft.com/2004/06/windows/eventlog/system">
<SubType Name="Transfer">0</SubType>
<Correlation ActivityID="00000000-0000-0000-0000-000000000000" />
</System>
<ApplicationData>Test41</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"
xmlns:te="http://schemas.microsoft.com/2004/06/E2ETraceEvent"
xmlns:s="http://schemas.microsoft.com/2004/06/windows/eventlog/system"
xmlns:sd="http://schemas.microsoft.com/2004/08/System.Diagnostics"
xmlns:tr="http://schemas.microsoft.com/2004/10/E2ETraceEvent/TraceRecord"
exclude-result-prefixes="te s sd tr">
<xsl:output method="html" indent="no"/>
<xsl:template match="/">
<html>
<head>
</head>
<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="//te:E2ETraceEvent">
<xsl:variable name="level">
<xsl:value-of select=".//s:SubType/@Name"/>
</xsl:variable>
<xsl:variable name="description">
<xsl:value-of select=".//te:ApplicationData/text()"/>
</xsl:variable>
<tr>
<!-- APPLICATION DATA -->
<td>
<xsl:value-of select="$description"/>
</td>
<!-- LEVEL -->
<td>
<xsl:value-of select="$level"/>
</td>
<!-- ACTIVITY NAME -->
<td>
<xsl:value-of select="((. | preceding-sibling::te:E2ETraceEvent)[s:System/s:SubType/@Name='Start'])[last()]/te:ApplicationData"/>
</td>
<!-- ACTIVITY ID -->
<td>
<xsl:value-of select=".//s:Correlation/@ActivityID"/>
</td>
</tr>
</xsl:for-each>
</tbody>
</table>
</div>
</div>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
输出
您的伪代码有点神秘(好像没有 Level==Start 的记录)。此外,XSLT 不是那样工作的。在 XSLT 中,查找是使用 key 完成的。
尝试将其添加到样式表的顶层:
<xsl:key name="start" match="te:E2ETraceEvent[s:System/s:SubType/@Name='Start']" use="s:System/s:Correlation/@ActivityID" />
然后将此列添加到您的 table:
<td>
<xsl:value-of select="key('start', s:System/s:Correlation/@ActivityID)/te:ApplicationData"/>
</td>