-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathSaxonMessageListener.cs
More file actions
99 lines (82 loc) · 3.08 KB
/
SaxonMessageListener.cs
File metadata and controls
99 lines (82 loc) · 3.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
using System;
using Saxon.Api;
namespace XsltDebugger.DebugAdapter;
internal sealed class SaxonMessageListener : IMessageListener2
{
public void Message(XdmNode content, QName errorCode, bool terminate, IXmlLocation location)
{
var messageText = content?.StringValue ?? string.Empty;
var locationText = FormatLocation(location);
var prefix = terminate ? "[xsl:message terminate]" : "[xsl:message]";
if (!string.IsNullOrEmpty(locationText))
{
prefix = $"{prefix} {locationText}";
}
if (!string.IsNullOrEmpty(messageText))
{
XsltEngineManager.NotifyOutput($"{prefix} {messageText}");
// Parse debug messages in format: [DBG] variableName value
TryParseDebugMessage(messageText);
}
else
{
XsltEngineManager.NotifyOutput(prefix);
}
}
private static void TryParseDebugMessage(string messageText)
{
// Expected format: "[DBG] variableName value"
// or sequence format: "[DBG] variableName value" (from xsl:message select="('[DBG]', 'varName', string($var))")
// Function parameters format: "[function functionName] param paramName value" (informational only, not captured)
if (string.IsNullOrWhiteSpace(messageText))
{
return;
}
var trimmed = messageText.Trim();
// Skip function parameter messages (start with "[function")
if (trimmed.StartsWith("[function", StringComparison.OrdinalIgnoreCase))
{
return;
}
// Handle sequence format: "[DBG] variableName value"
if (trimmed.StartsWith("[DBG]", StringComparison.OrdinalIgnoreCase))
{
// Remove "[DBG]" prefix
var content = trimmed.Substring(5).Trim();
// Split into variable name and value
// Expected: "variableName value"
var parts = content.Split(new[] { ' ' }, 2, StringSplitOptions.RemoveEmptyEntries);
if (parts.Length >= 1)
{
var varName = parts[0].Trim();
var varValue = parts.Length >= 2 ? parts[1].Trim() : string.Empty;
// Add to Variables dictionary
XsltEngineManager.Variables[varName] = varValue;
if (XsltEngineManager.IsLogEnabled)
{
XsltEngineManager.NotifyOutput($"[debug] Captured variable: ${varName} = {varValue}");
}
}
}
}
private static string FormatLocation(IXmlLocation location)
{
if (location == null)
{
return string.Empty;
}
var uri = location.BaseUri;
var line = location.LineNumber;
var lineString = line > 0 ? $":{line}" : string.Empty;
if (uri == null && string.IsNullOrEmpty(lineString))
{
return string.Empty;
}
var path = string.Empty;
if (uri != null)
{
path = uri.IsFile ? uri.LocalPath : uri.ToString();
}
return $"{path}{lineString}".Trim();
}
}