c#Linq To XML 相同的元素名称

本文关键字:元素 To XML c#Linq | 更新日期: 2023-09-27 17:55:08

我有一个小问题。我有一个XML文件,其中所有1级元素都具有相同的元素名称,并且可以通过Name属性进行区分。我无法更改 XML 文件。

下面是 XML 文件的示例:

<XProperty Name="DeviceInfo" FileVersion="1" xmlns="x-schema:XPropertySchema.xml" xmlns:dt="urn:schemas-microsoft-com:datatypes">
<Value dt:dt="i4">34</Value>
<Reserved>0</Reserved>
<XProperty Name="Manufacturer">
</XProperty>
<XProperty Name="ModelName">
    <Value>Advantage N-SL</Value>
    <Reserved>0</Reserved>
</XProperty>
<XProperty Name="SerialNumber">
    <Value>N40000</Value>
    <Reserved>0</Reserved>
</XProperty>

现在,在 c# 和 Linq to XML 中,我需要的是一些代码来设置特定 XProperty 节点的 Value 子节点的值。例如,对于名称为"序列号"的 XProperty 节点,将"值"子节点的值设置为"XYZ"。

第二个例子:要更改的值也可能是几个后代(这是可变的).xml:

 <XProperty Name="Versions">
        <XProperty Name="Parameters" Persistent="yes">
            <ShortDescription>Name</ShortDescription>
            <LongDescription>Version object</LongDescription>
            <Reserved>0</Reserved>
            <XProperty Name="Index" Persistent="yes">
                <ShortDescription>VersionIndex</ShortDescription>
                <Value dt:dt="i4">1</Value>
                <Reserved>0</Reserved>
            </XProperty>
        </XProperty>
    </XProperty>

我需要更改索引的值。

包含要更改的元素的类:

public class XmlChanger
    {
        public string File { get; set; }
        public string Key { get; set; }
        public XmlChanger ChildKey { get; set; }
        public string ChildKeyString { get; set; }
    }

因此,使用相同的代码,我需要示例 1 和示例 2 才能工作。

在某些情况下,值子节点可能不存在,在这种情况下,我需要添加它。

知道最好的方法是什么吗?

附言。我在解释时遇到了一些问题,但我希望有人明白它的含义。

提前感谢!

c#Linq To XML 相同的元素名称

使用类似这样的东西:

var doc = XDocument.Parse(xml);
var element = doc.Root.Elements().
                  Where(x => x.Name.LocalName == "XProperty" && 
                             x.Attributes().Any(
                                 y => y.Name == "Name" &&
                                 y.Value == "DeviceInfo")
                       ).SingleOrDefault();
if(element != null)
{    
    // change it
}
else
{
    // add a new one
    doc.Root.Add(new XElement(doc.Root.Name.Namespace+ "XProperty", 
                              new XAttribute("Name", "DeviceInfo2")));
}

我使用了这个 XML 定义:

var xml = @"<xml xmlns=""x-schema:XPropertySchema.xml"" xmlns:dt=""urn:schemas-microsoft-com:datatypes"">
<XProperty Name=""DeviceInfo"" FileVersion=""1"">
<Value dt:dt=""i4"">34</Value>
<Reserved>0</Reserved>
</XProperty>
<XProperty Name=""Manufacturer"">
</XProperty>
<XProperty Name=""ModelName"">
    <Value>Advantage N-SL</Value>
    <Reserved>0</Reserved>
</XProperty>
<XProperty Name=""SerialNumber"">
    <Value>N40000</Value>
    <Reserved>0</Reserved>
</XProperty>
</xml>";

我在 LINQPad 中创建了此代码,并使用字符串变量来保存 xml 文件。在这种情况下,我需要解析。如果要直接从文件加载XML,XDocument.Load是正确的方法

var docx = XDocument.Load("someUri");
var elements = docx.Elements(XName.Get("XProperty")).Where(x => x.Attributes().Count(a => a.Name == XName.Get("Name") && a.Value == "SerialNumber") > 0);
foreach (var e in elements)
{
    if (e.Elements().Count(x => x.Name == XName.Get("Value")) == 1)
    {
        e.Elements().Single(x => x.Name == XName.Get("Value")).Value = "XYZ";
    }
    else
    {
        e.Add(new XElement(XName.Get("Value"), "XYZ"));
    }
}

我没有对你的XML片段包含的命名空间做出让步,所以你将不得不把它添加到XName.Get()方法中。