Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/Schematron/Config.cs
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ public static void Setup()
{
System.Diagnostics.Trace.Write("Loading schematron statics...");
System.Diagnostics.Trace.Write(CompiledExpressions.Schema.ReturnType);
System.Diagnostics.Trace.Write(TagExpressions.Dir.RightToLeft);
System.Diagnostics.Trace.Write(TagExpressions.Dir().RightToLeft);
System.Diagnostics.Trace.WriteLine(FormattingUtils.XmlErrorPosition.RightToLeft);
}
}
2 changes: 1 addition & 1 deletion src/Schematron/Formatters/LogFormatter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public override void Format(Test source, XPathNavigator context, StringBuilder o
{
var sb = FormatMessage(source, context, source.Message);
// Finally remove any non-name schematron tag in the message.
var res = TagExpressions.AllSchematron.Replace(sb.ToString(), string.Empty);
var res = TagExpressions.AllSchematron().Replace(sb.ToString(), string.Empty);
sb = new StringBuilder();
if (source is Assert)
{
Expand Down
2 changes: 1 addition & 1 deletion src/Schematron/Formatters/XmlFormatter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public override void Format(Test source, XPathNavigator context, StringBuilder o
msg = FormatMessage(source, context, msg).ToString();

// Finally remove any non-name schematron tag in the message.
var res = TagExpressions.AllSchematron.Replace(msg, string.Empty);
var res = TagExpressions.AllSchematron().Replace(msg, string.Empty);

//Accumulate namespaces found during traversal of node for its position.
var ns = new Hashtable();
Expand Down
4 changes: 2 additions & 2 deletions src/Schematron/Schematron.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<PropertyGroup>
<AssemblyName>Schematron</AssemblyName>
<RootNamespace>Schematron</RootNamespace>
<TargetFramework>netstandard2.0</TargetFramework>
<TargetFrameworks>netstandard2.0;net8.0</TargetFrameworks>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<PackageId>Schematron.NET</PackageId>
<LangVersion>Latest</LangVersion>
Expand All @@ -13,7 +13,7 @@
<InternalsVisibleTo Include="Schematron.Tests" />
</ItemGroup>

<ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
<PackageReference Include="PolySharp" Version="1.15.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
Expand Down
89 changes: 60 additions & 29 deletions src/Schematron/TagExpressions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,41 +3,72 @@
namespace Schematron;

/// <summary />
class TagExpressions
partial class TagExpressions
{
#if NET8_0_OR_GREATER
/// <summary>
/// The compiled regular expression to replace the special <c>name</c> and <c>value</c> tags inside a message.
/// </summary>
/// <remarks>
/// Replaces each instance of <c>name</c> and <c>value</c>tags with the value in the current context element.
/// </remarks>
public static Regex NameValueOf;

public static Regex Emph;
public static Regex Dir;
public static Regex Span;
public static Regex Para;
public static Regex Any;
public static Regex AllSchematron;

/// <summary />
static TagExpressions()
{
// The element declarations can contain the namespace if expanded in a loaded document.
NameValueOf = new Regex(@"<[^\s>]*\b(name|value-of)\b[^>]*/>", RegexOptions.Compiled);
Emph = new Regex(@"<[^\s>]*\bemph\b[^>]*>", RegexOptions.Compiled);
Dir = new Regex(@"<[^\s]*\bdir\b[^>]*>", RegexOptions.Compiled);
Span = new Regex(@"<[^\s]*\bspan\b[^>]*>", RegexOptions.Compiled);
Para = new Regex(@"<[^\s]*\bp\b[^>]*>", RegexOptions.Compiled);
Any = new Regex(@"<[^\s]*[^>]*>", RegexOptions.Compiled);
// Closing elements don't have an expanded xmlns so they will be matched too.
// TODO: improve this to avoid removing non-schematron closing elements.
var nsPattern = "(?:" + Regex.Escape(Schema.LegacyNamespace) + "|" + Regex.Escape(Schema.IsoNamespace) + ")";
AllSchematron = new Regex(@"<.*\bxmlns\b[^\s]*" + nsPattern + "[^>]*>|</[^>]*>", RegexOptions.Compiled);
}

TagExpressions()
{
}
// The element declarations can contain the namespace if expanded in a loaded document.
[GeneratedRegex(@"<[^\s>]*\b(name|value-of)\b[^>]*/>")]
public static partial Regex NameValueOf();

[GeneratedRegex(@"<[^\s>]*\bemph\b[^>]*>")]
public static partial Regex Emph();

[GeneratedRegex(@"<[^\s]*\bdir\b[^>]*>")]
public static partial Regex Dir();

[GeneratedRegex(@"<[^\s]*\bspan\b[^>]*>")]
public static partial Regex Span();

[GeneratedRegex(@"<[^\s]*\bp\b[^>]*>")]
public static partial Regex Para();

[GeneratedRegex(@"<[^\s]*[^>]*>")]
public static partial Regex Any();

// Closing elements don't have an expanded xmlns so they will be matched too.
// TODO: improve this to avoid removing non-schematron closing elements.
// Pattern derived from Regex.Escape(Schema.LegacyNamespace) and Regex.Escape(Schema.IsoNamespace).
// If those constants ever change, update the hardcoded escaped values here to match.
[GeneratedRegex(@"<.*\bxmlns\b[^\s]*(?:http://www\.ascc\.net/xml/schematron|http://purl\.oclc\.org/dsdl/schematron)[^>]*>|</[^>]*>")]
public static partial Regex AllSchematron();
#else
/// <summary>
/// The compiled regular expression to replace the special <c>name</c> and <c>value</c> tags inside a message.
/// </summary>
/// <remarks>
/// Replaces each instance of <c>name</c> and <c>value</c>tags with the value in the current context element.
/// </remarks>
// The element declarations can contain the namespace if expanded in a loaded document.
static readonly Regex _nameValueOf = new Regex(@"<[^\s>]*\b(name|value-of)\b[^>]*/>", RegexOptions.Compiled);
public static Regex NameValueOf() => _nameValueOf;

static readonly Regex _emph = new Regex(@"<[^\s>]*\bemph\b[^>]*>", RegexOptions.Compiled);
public static Regex Emph() => _emph;

static readonly Regex _dir = new Regex(@"<[^\s]*\bdir\b[^>]*>", RegexOptions.Compiled);
public static Regex Dir() => _dir;

static readonly Regex _span = new Regex(@"<[^\s]*\bspan\b[^>]*>", RegexOptions.Compiled);
public static Regex Span() => _span;

static readonly Regex _para = new Regex(@"<[^\s]*\bp\b[^>]*>", RegexOptions.Compiled);
public static Regex Para() => _para;

static readonly Regex _any = new Regex(@"<[^\s]*[^>]*>", RegexOptions.Compiled);
public static Regex Any() => _any;

// Closing elements don't have an expanded xmlns so they will be matched too.
// TODO: improve this to avoid removing non-schematron closing elements.
static readonly Regex _allSchematron = new Regex(
@"<.*\bxmlns\b[^\s]*(?:" + Regex.Escape(Schema.LegacyNamespace) + "|" + Regex.Escape(Schema.IsoNamespace) + @")[^>]*>|</[^>]*>",
RegexOptions.Compiled);
public static Regex AllSchematron() => _allSchematron;
#endif
}

2 changes: 1 addition & 1 deletion src/Schematron/Test.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public Test(string test, string message) : base(test)
// Save <name> and <value-of> tags in the message and their paths / selects in their compiled form.
// TODO: see if we can work with the XML in the message, instead of using RE.
// TODO: Check the correct usage of path and select attributes.
NameValueOfExpressions = TagExpressions.NameValueOf.Matches(Message);
NameValueOfExpressions = TagExpressions.NameValueOf().Matches(Message);
var nc = NameValueOfExpressions.Count;
NamePaths = new XPathExpression[nc];
ValueOfSelects = new XPathExpression[nc];
Expand Down
Loading