我试图将这些 node priceqtyamount插入子体Apple>Store仅使用属性查找插入的确切位置.

<?xml version="1.0" encoding="utf-8"?>
<Fruits>
    <node text="Apple" tag="a" imageindex="0">
        <node text="Store" tag="b" imageindex="1" />
        <node text="City" tag="c" imageindex="2" />
    </node>
    <node text="Orange" tag="a" imageindex="0">
        <node text="Store" tag="b" imageindex="1" />
        <node text="City" tag="c" imageindex="2" />
    </node>
</Fruits>

预期结果:

<?xml version="1.0" encoding="utf-8"?>
<Fruits>
    <node text="Apple" tag="a" imageindex="0">
        <node text="Store" tag="b" imageindex="1" />
            <node text="price" tag="b" imageindex="1" />
            <node text="qty" tag="b" imageindex="1" />
            <node text="amount" tag="b" imageindex="1" />
        <node text="City" tag="c" imageindex="2" />
    </node>
    <node text="Orange" tag="a" imageindex="0">
        <node text="Store" tag="b" imageindex="1" />
        <node text="City" tag="c" imageindex="2" />
    </node>
</Fruits>

以下是我到目前为止所做的.我很难使用该属性定义detail路径.我知道Linq to XML有一个直接的方法,但无法理解.虽然我试了foreach次,但没有成功,至少对我来说,它变得更复杂了.

XElement xFruit = XElement.Load(@"D:\Xml\Fruit.xml");

XElement detail = xFruit...

detail.Add(
    new XElement("price", "$10"),
    new XElement("qty", "10"),
    new XElement("amount", "$100")
);

xFruit.Save(@"D:\Xml\Fruit.xml");

任何帮助都将不胜感激!

推荐答案

您正在使用名为"text"的属性定义插入位置的路径.为了使迭代到该位置变得简单,您可以try 编写一个简单的FindPath扩展,knows"text"属性就是要查找的扩展,然后像这样调用该扩展:

var detail = xFruit.FindPath(@"Apple\Store");
detail?.Add(
        new XElement("price", "$10"),
        new XElement("qty", "10"),
        new XElement("amount", "$100")
);

所以在顶级静态类中...

static class Extensions
{

首先进行扩展以获取属性的值(如果属性存在),如果属性不存在,则不会引发异常(FindPath扩展将使用它来判断"text"属性).

    public static bool TryGetAttributeValue(
        this XElement xel,
        string name,
        out string value)
    {
        var attr = xel.Attributes()
            .FirstOrDefault(@try => string.Equals(name, @try.Name.LocalName));
        if (attr == null)
        {
            value = string.Empty;
            return false;
        }
        else
        {
            value = attr.Value;
            return true;
        }
    }

这使得编写第二个扩展变得很简单,该扩展迭代以在路径上查找 node (如果存在),如果不存在,则返回null.(该方法采用比您提到的foreach次迭代更直接的路径.)

    public static XElement FindPath(
        this XElement xRoot,
        string path)
    {
        XElement xTraverse = xRoot;
        string[] split = path.Split('\\');
        for (int i = 0; i < split.Length; i++)
        {
            xTraverse =
                xTraverse.Elements()
                .FirstOrDefault(match =>
                    match.TryGetAttributeValue("text", out string value) &&
                    (value == split[i]));
            if (xTraverse == null) break;
        }
        return xTraverse;
    }
}

TESTBENCH

static void Main(string[] args)
{
    var xFruit = XElement.Parse(source);
    var detail = xFruit.FindPath(@"Apple\Store");
    detail?.Add(
            new XElement("price", "$10"),
            new XElement("qty", "10"),
            new XElement("amount", "$100")
    );
    Console.WriteLine(xFruit.ToString());
}
const string source =
@"<Fruits>
    <node text=""Apple"" tag=""a"" imageindex=""0"">
        <node text = ""Store"" tag=""b"" imageindex=""1"" />
        <node text = ""City"" tag=""c"" imageindex=""2"" />
    </node>
    <node text = ""Orange"" tag=""a"" imageindex=""0"">
        <node text = ""Store"" tag=""b"" imageindex=""1"" />
        <node text = ""City"" tag=""c"" imageindex=""2"" />
    </node>
</Fruits>";

这应该与您想要的输出相匹配.

console output

Csharp相关问答推荐

ListaryImportProperty的默认DllImportSearchPathsProperty行为

react 式扩展连接中的非交叉LeftDurationTimeout

并行令牌更新

迭代C#List并在数据库中 for each 元素执行SELECT语句—更有效的方式?

为什么C#Bigbit不总是相同的比特长度?

当通过Google的Gmail Api发送邮件时,签名会产生dkim = neutral(正文散列未验证)'

发布用于Linux Ubuntu的C#应用程序

SortedSet.Remove()不会删除SortedSet.Min返回的元素

如何使用MoQ模拟Resources GroupCollection?

显示文档的ECDsa签名PDF在Adobe Reader中签名后已被更改或损坏

从另一个不同 struct 的数组创建Newtonsoft.Json.Linq.J数组

EF核心区分大小写的主键

在.NET 8最低API中从表单绑定中排除属性

使用switch 类型模式时出现奇怪的编译器行为

多个选项卡上的MudForm验证

在同一个捕获中可以有多种类型的异常吗?

如何在C#控制台应用程序中获取用户输入并将其作为订单项目进行处理?

如何在Xamarin.Forms中检索PanGesture事件的位置?

我是否以错误的方式使用了异步延迟初始化?

ASP.NET文件上传不接受超过10MB的文件