diff --git a/YangParser/Generator/YangGenerator.cs b/YangParser/Generator/YangGenerator.cs
index 1c3aaba..e1a6ffa 100644
--- a/YangParser/Generator/YangGenerator.cs
+++ b/YangParser/Generator/YangGenerator.cs
@@ -363,6 +363,11 @@ public class TargetAttribute(string xPath) : Attribute
{
public string XPath { get; } = xPath;
}
+ [AttributeUsage(AttributeTargets.All, AllowMultiple = true)]
+ public class XPathAttribute(string path) : Attribute
+ {
+ public string Path { get; } = path;
+ }
[AttributeUsage(AttributeTargets.All, AllowMultiple = false)]
public class KeyAttribute(params string[] value) : Attribute
{
diff --git a/YangParser/SemanticModel/Action.cs b/YangParser/SemanticModel/Action.cs
index e316217..13e2a5e 100644
--- a/YangParser/SemanticModel/Action.cs
+++ b/YangParser/SemanticModel/Action.cs
@@ -43,7 +43,7 @@ public override string ToCode()
builder.AppendLine(
$"public static {returnType} {MakeName(Argument)}(IChannel channel, int messageID{inputType})");
builder.AppendLine("{");
- var ns = Parent is Module module ? "xmlns=\\\"" + module.XmlNamespace.Argument + "\\\"" : string.Empty;
+ var ns = Parent is Module module ? $"xmlns:{module.XmlNamespace?.Prefix}=\\\"" + module.XmlNamespace?.Namespace + "\\\"" : string.Empty;
builder.AppendLine(inputType != string.Empty
? $$"""
var xml = $"<{{Argument}} {{ns}}>{input.ToXML()}{{Argument}}>";
diff --git a/YangParser/SemanticModel/BelongsTo.cs b/YangParser/SemanticModel/BelongsTo.cs
index de285f1..e91b0d8 100644
--- a/YangParser/SemanticModel/BelongsTo.cs
+++ b/YangParser/SemanticModel/BelongsTo.cs
@@ -14,7 +14,7 @@ public BelongsTo(YangStatement statement) : base(statement)
public override ChildRule[] PermittedChildren { get; } =
[
- new ChildRule(Prefix.Keyword, Cardinality.Required)
+ new ChildRule(SemanticModel.Prefix.Keyword, Cardinality.Required)
];
public override string ToCode()
diff --git a/YangParser/SemanticModel/Grouping.cs b/YangParser/SemanticModel/Grouping.cs
index 714f936..34b727d 100644
--- a/YangParser/SemanticModel/Grouping.cs
+++ b/YangParser/SemanticModel/Grouping.cs
@@ -1,4 +1,3 @@
-using System;
using System.Linq;
using YangParser.Generator;
using YangParser.Parser;
@@ -41,7 +40,7 @@ public override string ToCode()
public IStatement[] WithUse(Uses use)
{
var copy = StatementFactory.Create(Source);
- Parent.Insert([copy]);
+ Parent!.Insert([copy]);
copy.Parent = Parent;
foreach (var child in copy.Unwrap())
{
@@ -123,12 +122,13 @@ public IStatement[] WithUse(Uses use)
var current = copy;
foreach (var element in path)
{
- var prefix = element.Prefix(out var name);
+ element.Prefix(out var name);
var origin = current;
current = origin.Children.FirstOrDefault(c => c.Argument == name);
if (current is null)
{
- Log.Write($"Could not find part '{name}' of path {refinement.Argument} in source {origin}");
+ Log.Write(
+ $"Could not find part '{name}' of path {refinement.Argument} in source {origin.Source.Keyword} {origin.Argument}");
break; //Target not present, nothing to refine.
}
}
diff --git a/YangParser/SemanticModel/IStatement.cs b/YangParser/SemanticModel/IStatement.cs
index ae5515d..e2b73de 100644
--- a/YangParser/SemanticModel/IStatement.cs
+++ b/YangParser/SemanticModel/IStatement.cs
@@ -5,7 +5,7 @@ namespace YangParser.SemanticModel;
public interface IStatement
{
- string Argument { get; set; }
+ string Argument { get; set; }
ChildRule[] PermittedChildren { get; }
HashSet Attributes { get; }
HashSet Keywords { get; }
@@ -18,6 +18,9 @@ public interface IStatement
string ToCode();
void Replace(IStatement child, IEnumerable replacements);
void Insert(IEnumerable augments);
+ string XPath { get; }
+ (string Namespace, string Prefix)? XmlNamespace { get; set; }
+ string Prefix { get; }
}
public interface ICommentable : IStatement
diff --git a/YangParser/SemanticModel/Import.cs b/YangParser/SemanticModel/Import.cs
index 56410cd..b4bdc15 100644
--- a/YangParser/SemanticModel/Import.cs
+++ b/YangParser/SemanticModel/Import.cs
@@ -10,19 +10,8 @@ public Import(YangStatement statement) : base(statement)
{
if (statement.Keyword != Keyword)
throw new SemanticError($"Non-matching Keyword '{statement.Keyword}', expected {Keyword}", statement);
-
- Revision = Children.FirstOrDefault(child => child is RevisionDate)?.Argument;
- Prefix = Children.First(child => child is Prefix).Argument;
- var reference = Children.FirstOrDefault(child => child is Reference);
- var description = Children.FirstOrDefault(child => child is Description);
- AdditionalInformation = reference is null ? string.Empty : $"Reference: \"{reference.Argument}\", ";
- AdditionalInformation += description is null ? string.Empty : $"Description: \"{description}\"";
}
- private readonly string? Revision;
- private readonly string Prefix;
- private readonly string? AdditionalInformation;
-
public const string Keyword = "import";
public override ChildRule[] PermittedChildren { get; } =
diff --git a/YangParser/SemanticModel/Module.cs b/YangParser/SemanticModel/Module.cs
index ab9cc4f..49fb196 100644
--- a/YangParser/SemanticModel/Module.cs
+++ b/YangParser/SemanticModel/Module.cs
@@ -11,9 +11,9 @@ public Module(YangStatement statement) : base(statement)
{
if (statement.Keyword != Keyword)
throw new SemanticError($"Non-matching Keyword '{statement.Keyword}', expected {Keyword}", statement);
- XmlNamespace = Children.First(child => child is Namespace);
var localPrefix = this.GetChild().Argument;
var localNS = MakeNamespace(Argument) + ".YangNode.";
+ XmlNamespace = (Children.First(child => child is Namespace).Argument, localPrefix);
Usings = new()
{
[localPrefix] = localNS
@@ -64,9 +64,6 @@ public Module(YangStatement statement) : base(statement)
}
public Dictionary ImportedModules { get; } = [];
-
-
- public IStatement XmlNamespace { get; set; }
public Dictionary Usings { get; }
public string Namespace { get; private set; }
@@ -91,7 +88,7 @@ public Module(YangStatement statement) : base(statement)
new ChildRule(SemanticModel.Namespace.Keyword, Cardinality.Required),
new ChildRule(Notification.Keyword, Cardinality.ZeroOrMore),
new ChildRule(Organization.Keyword),
- new ChildRule(Prefix.Keyword, Cardinality.Required),
+ new ChildRule(SemanticModel.Prefix.Keyword, Cardinality.Required),
new ChildRule(Reference.Keyword),
new ChildRule(Revision.Keyword, Cardinality.ZeroOrMore),
new ChildRule(Rpc.Keyword, Cardinality.ZeroOrMore),
diff --git a/YangParser/SemanticModel/Rpc.cs b/YangParser/SemanticModel/Rpc.cs
index 8a1cc3d..1238671 100644
--- a/YangParser/SemanticModel/Rpc.cs
+++ b/YangParser/SemanticModel/Rpc.cs
@@ -54,7 +54,7 @@ public override string ToCode()
builder.AppendLine(
$"public static {returnType} {MakeName(Argument)}(IChannel channel, int messageID{inputType})");
builder.AppendLine("{");
- var ns = Parent is Module module ? "xmlns=\\\"" + module.XmlNamespace.Argument + "\\\"" : string.Empty;
+ var ns = Parent is Module module ? $"xmlns:{module.XmlNamespace?.Prefix}=\\\"" + module.XmlNamespace?.Namespace + "\\\"" : string.Empty;
builder.AppendLine(inputType != string.Empty
? $$"""
var xml = $"<{{Argument}} {{ns}}>{input.ToXML()}{{Argument}}>";
diff --git a/YangParser/SemanticModel/Statement.cs b/YangParser/SemanticModel/Statement.cs
index b458565..3b78f78 100644
--- a/YangParser/SemanticModel/Statement.cs
+++ b/YangParser/SemanticModel/Statement.cs
@@ -5,6 +5,7 @@
using System.Text.RegularExpressions;
using YangParser.Parser;
using YangParser.SemanticModel.Builtins;
+using String = System.String;
namespace YangParser.SemanticModel;
@@ -23,6 +24,12 @@ protected Statement(YangStatement statement, bool validate = true)
Children = statement.Children.Select(StatementFactory.Create).ToArray();
}
+ public (string Namespace, string Prefix)? XmlNamespace { get; set; }
+ public string Prefix => XmlNamespace?.Prefix ?? Parent?.Prefix ?? string.Empty;
+
+ public string XPath => ((Parent?.XPath ?? String.Empty) + "/").Replace("//", "/") +
+ (string.IsNullOrEmpty(Prefix) ? string.Empty : Prefix + ":") + Source.Argument;
+
public YangStatement Source { get; set; }
private IStatement[] _children = [];
@@ -76,7 +83,7 @@ public static string MakeName(string argument)
var prefix = argument.Prefix(out var value);
var addColon = !prefix.Contains('.') && !string.IsNullOrWhiteSpace(prefix);
- foreach (var section in value.Split('-', ' ', '/', '.','^'))
+ foreach (var section in value.Split('-', ' ', '/', '.', '^'))
{
output.Append(Capitalize(section));
}
@@ -124,9 +131,14 @@ protected static string TypeName(Type type)
protected string KeywordString => " " + string.Join(" ", Keywords) + (Keywords.Count > 0 ? " " : "");
- public string AttributeString => Attributes.Count > 0
- ? "\n" + string.Join("\n", Attributes.OrderBy(x => x.Length).Select(attr => $"[{attr}]"))
- : string.Empty;
+ public string AttributeString
+ {
+ get
+ {
+ Attributes.Add("XPath(\"" + XPath + '"' + ')');
+ return "\n" + string.Join("\n", Attributes.OrderBy(x => x.Length).Select(attr => $"[{attr}]"));
+ }
+ }
public string DescriptionString => $"""
///