我有一个小问题。我有一个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#&amp; Linq to XML,是一些代码,用于设置特定XProperty节点的Value子节点的值。例如,对于名称为“SerialNumber”的XProperty节点,将Value子节点的值设置为“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>
我需要更改Index的值。
包含要更改的元素的类:
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。
在某些情况下,Value子节点可能不存在,在这种情况下我需要添加它。
知道最好的方法是什么?
PS。我有一些问题需要解释,但我希望有人知道它的含义是什么。
提前致谢!
答案 0 :(得分:3)
使用类似的东西:
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文件。在这种情况下,我需要Parse。如果要直接从文件加载XML,XDocument.Load是正确的方法
答案 1 :(得分:1)
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片段包含的Namespace做出让步,所以你必须将它添加到XName.Get()方法中。