Add more CRUD.
This commit is contained in:
parent
f4a563a9d4
commit
9a3f91e41c
28
Transformation/Bangs/AfterBang.cs
Normal file
28
Transformation/Bangs/AfterBang.cs
Normal file
@ -0,0 +1,28 @@
|
||||
using System.Xml.Linq;
|
||||
using XNeedle.Parser.Elements;
|
||||
|
||||
namespace XNeedle.Transformation.Bangs
|
||||
{
|
||||
public class AfterBang : BangOperation
|
||||
{
|
||||
public override string Name => "after";
|
||||
|
||||
public override Context Execute(Context ctx, IEnumerable<string> arguments)
|
||||
{
|
||||
if (ctx.Node == null)
|
||||
{
|
||||
throw new ArgumentNullException("!after needs a reachable node");
|
||||
}
|
||||
if (arguments.Count() < 1)
|
||||
{
|
||||
throw new ArgumentException("!after needs at least the tag name as argument.");
|
||||
}
|
||||
|
||||
var tagname = arguments.ElementAt(0);
|
||||
var element = new XElement(tagname, "");
|
||||
ctx.Node.AddAfterSelf(element);
|
||||
|
||||
return new Context{ Node = element, SLoc = ctx.SLoc.AsSynthetic(), XPathSelector = tagname};
|
||||
}
|
||||
}
|
||||
}
|
||||
28
Transformation/Bangs/BeforeBang.cs
Normal file
28
Transformation/Bangs/BeforeBang.cs
Normal file
@ -0,0 +1,28 @@
|
||||
using System.Xml.Linq;
|
||||
using XNeedle.Parser.Elements;
|
||||
|
||||
namespace XNeedle.Transformation.Bangs
|
||||
{
|
||||
public class BeforeBang : BangOperation
|
||||
{
|
||||
public override string Name => "before";
|
||||
|
||||
public override Context Execute(Context ctx, IEnumerable<string> arguments)
|
||||
{
|
||||
if (ctx.Node == null)
|
||||
{
|
||||
throw new ArgumentNullException("!before needs a reachable node");
|
||||
}
|
||||
if (arguments.Count() < 1)
|
||||
{
|
||||
throw new ArgumentException("!before needs at least the tag name as argument.");
|
||||
}
|
||||
|
||||
var tagname = arguments.ElementAt(0);
|
||||
var element = new XElement(tagname, "");
|
||||
ctx.Node.AddBeforeSelf(element);
|
||||
|
||||
return new Context{ Node = element, SLoc = ctx.SLoc.AsSynthetic(), XPathSelector = tagname};
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -113,7 +113,7 @@ namespace XNeedle.Transformation
|
||||
{
|
||||
if (ctx.Node == null)
|
||||
{
|
||||
throw new ArgumentNullException("!seap needs a reachable node");
|
||||
throw new ArgumentNullException("!swap needs a reachable node");
|
||||
}
|
||||
|
||||
var a_node = ctx.Node.XPathSelectElement(a_select);
|
||||
@ -131,5 +131,61 @@ namespace XNeedle.Transformation
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
public static string remove(Context ctx, string select)
|
||||
{
|
||||
if (ctx.Node == null)
|
||||
{
|
||||
throw new ArgumentNullException("!remove needs a reachable node");
|
||||
}
|
||||
|
||||
// Use ToList to make the lazy/generator enumeration concrete before applying operations
|
||||
var nodes = ctx.Node.XPathSelectElements(select).ToList();
|
||||
|
||||
foreach (var node in nodes)
|
||||
{
|
||||
node.Remove();
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
public static string rename(Context ctx, string newName)
|
||||
{
|
||||
if (ctx.Node is null) return "";
|
||||
var replacement = new XElement(newName, ctx.Node.Attributes(), ctx.Node.Nodes());
|
||||
ctx.Node.ReplaceWith(replacement);
|
||||
ctx.Node = replacement; // update context to point to new element
|
||||
return "";
|
||||
}
|
||||
|
||||
public static string rename(Context ctx, string select, string newName)
|
||||
{
|
||||
if (ctx.Node is null) return "";
|
||||
|
||||
int atIdx = select.IndexOf('@');
|
||||
if (atIdx >= 0)
|
||||
{
|
||||
// "Node@Attr" — rename an attribute
|
||||
var elementSelect = select[..atIdx].TrimEnd();
|
||||
var attrName = select[(atIdx + 1)..].TrimStart();
|
||||
var target = string.IsNullOrEmpty(elementSelect)
|
||||
? ctx.Node
|
||||
: ctx.Node.XPathSelectElement(elementSelect);
|
||||
var attr = target?.Attribute(attrName);
|
||||
if (attr is null) return "";
|
||||
attr.Remove();
|
||||
target!.SetAttributeValue(newName, attr.Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
// plain XPath select — rename element
|
||||
var target = ctx.Node.XPathSelectElement(select);
|
||||
if (target is null) return "";
|
||||
var replacement = new XElement(newName, target.Attributes(), target.Nodes());
|
||||
target.ReplaceWith(replacement);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user