我正在处理一堆XML,这些XML都共享一个包含字符串“name”的属性。以下代码选择其中包含字符串“name”的属性,并为其指定新值。
public void updateXmlFile(string strFileName)
{
try
{
//Load the Document
XmlDocument doc = new XmlDocument();
doc.Load(strFileName);
//Set the changed Value
string newValue = GetUniqueKey();
//Select all nodes in the XML then choose from them
//the first node that contain string "name" in it
XmlNodeList list = doc.SelectNodes("//@*");
XmlNode filteredNode = list.Cast<XmlNode>()
.First(item => item.Name.ToLower().Contains("name"));
//Assign the newValue to the value of the node
filteredNode.Value = newValue;
doc.Save(strFileName);
}
catch (XmlException xex) { Console.WriteLine(xex); }
}
现在添加了一个新的XML,它们中没有字符串“name”,因此我决定简单地修改最后一个属性,而不是修改其中的字符串“name”。第一个)
有人可以告诉我该怎么做吗?
修改
以下是我的XML
的示例<?xml version="1.0" encoding="utf-8"?>
<CO_CallSignLists Version="24" ModDttm="2010-09-13T06:45:38.873" ModUser="EUADEV\SARE100" ModuleOwner="EUADEVS06\SS2008" CreateDttm="2009-11-05T10:19:31.583" CreateUser="EUADEV\A003893">
<CoCallSignLists DataclassId="E3FC5E2D-FE84-492D-AD94-3ACCED870714" EntityId="E3FC5E2D-FE84-492D-AD94-3ACCED870714" MissionID="4CF71AB2-0D92-DE11-B5D1-000C46F3773D" BroadcastType="S" DeputyInSpecialList="1" SunSpots="1537634cb70c6d80">
<CoCallSigns EntityId="DEBF1DDB-3C92-DE11-A280-000C46F377C4" CmdID="C45F3EF1-1292-DE11-B5D1-000C46F3773D" ModuleID="6CB497F3-AD63-43F1-ACAE-2C5C3B1D7F61" ListType="HS" Name="Reda Sabassi" Broadcast="INTO" PhysicalAddress="37" IsGS="1" HCId="0" CommonGeoPos="1" GeoLat="0.0000000" GeoLong="0.0000000">
<CoRadios EntityId="E1BF1DDB-3C92-DE11-A280-000C46F377C4" RadioType="HF" />
</CoCallSigns>
</CoCallSignLists>
</CO_CallSignLists>
@Alex:您注意到“SunSpots”属性(第一个子元素中的最后一个属性)已成功更改。但现在,当我想将XML加载回数据库时,它会给我一个错误
这是修改后的代码
public void updateXmlFile(string strFileName)
{
try
{
XDocument doc = XDocument.Load(strFileName);
XAttribute l_attr_1 = (doc.Elements().First().Elements().First().Attributes().Last());
l_attr_1.Value = GetUniqueKey();
Console.WriteLine("Name: {0} Value:{1}", l_attr_1.Name, l_attr_1.Value);
doc.Save(strFileName);
}
catch (XmlException xex) { Console.WriteLine(xex); }
}
我正在考虑制作一个if语句来检查XML是否有一个包含字符串“name”的属性(因为我的大部分XML都有一个包含其中名称的属性),如果它确实改变了属性的值如果没有找到最后一个属性并改变它..不是最好的解决方案,只是把它扔出去
答案 0 :(得分:1)
我没有对此进行过测试,但您应该可以在XPath表达式中完成所有这些操作。像这样:
//@*[contains(node-name(.), 'name')][last()]
这将只返回名称中包含字符串name
的最后一个属性。
如果您只想要最后一个属性,无论其名称如何,请使用:
//@*[last()]
答案 1 :(得分:1)
然后肯定使用Linq到XML。 例如:
using System.Xml.Linq;
string xml = @"<?xml version=""1.0"" encoding=""utf-8""?>
<Commands Version=""439"" CreateUser=""Reda"">
<CmCommands DataclassId=""57067ca8-ef96-4d2e-a085-6bd7e8b24126"" OrderName = ""Tea"" Remark=""Black"">
<CmExecutions EntityId=""A9A5B0F2-6AB4-4619-9106-B0F85F86EE01"" Lock=""n"" />
</CmCommands>
</Commands>";
XDocument x = XDocument.Parse(xml);
Debug.Print(x.Elements().First().Elements().First().Attributes().Last().Value);
// Commands ^ CmCommands ^ Remark ^
即,逐字逐句,第一个元素的第一个子元素的最后一个属性。
您还可以查询元素/属性名称,例如:
Debug.Print(x.Descendants(XName.Get("CmCommands", "")).First().Attribute(XName.Get("Remark", "")).Value);
当然,你可以使用所有的Linq善良,如Where,Select,Any,All等。
注意:如果合适,请将XDocument.Parse替换为XDocument.Load等。
答案 2 :(得分:0)
查看班级XmlAttributeCollection。您可以通过读取属性XmlNode的属性来获取此集合。只需通过索引获取最后一个。
答案 3 :(得分:0)
使用这样的扩展方法代替.First()
:
public static T LastOrDefault<T>(this IEnumerable<T> list)
{
T val = null;
foreach(T item in list)
{
val = item;
}
return val;
}