我正在学习XML查询和Xdocuments,并且无法更新现有元素的属性。这是我的WCF服务。第二部分工作(创建带有属性的新元素。问题是我的查询不能返回任何结果,代码总是添加一个新元素。
//this will insert the officer location and status into the xml data file
//I read about how to do this at http://prathapk.net/creating-wcf-service-to-store-read-data-in-xml-database/
//and https://msdn.microsoft.com/en-us/library/bb387041.aspx
public void InsertOfficerData(string OfficerID, double latitude, double longitude, int StatusCode)
{
//open xml file
XDocument doc = XDocument.Load(HttpContext.Current.Server.MapPath("Officers.xml"));
//linq query to find the element with the officer ID if it exists
IEnumerable<XElement> officer =
from el in doc.Element("Officers").Elements("Officer")
where (string)el.Attribute("OfficerID") == OfficerID
select el;
bool updated = false;
//update officer attributes
foreach (XElement el in officer)
{
//update attributes
el.Attribute("Latitude").Value = Convert.ToString(latitude);
updated = true;
doc.Save(HttpContext.Current.Server.MapPath("Officers.xml"));
}
//if an officer with the id was not found
if (!updated)
{
//add the element with attributes
doc.Element("Officers").Add(new XElement("Officer",
new XAttribute("ID", OfficerID),
new XAttribute("Latitude", latitude),
new XAttribute("Longitude", longitude),
new XAttribute("Status", StatusCode)));
doc.Save(HttpContext.Current.Server.MapPath("Officers.xml"));
}
}
我的XML文件结构示例:
<?xml version="1.0" encoding="utf-8"?>
<Officers>
<Officer ID="Dust" Latitude="4" Longitude="5" Status="3" />
</Officers>
答案 0 :(得分:2)
您正在检查vs名为OfficerID
的属性,但您只使用新的ID
变量创建名为OfficerID
的属性。
更改
where (string)el.Attribute("OfficerID") == OfficerID
是
where (string)el.Attribute("ID") == OfficerID
OR
更改
new XAttribute("ID", OfficerID),
是
new XAttribute("OfficerID", OfficerID),
另一件可能至关重要的事情是,即使你找到了军官,搜索还没有发生,直到你成功。可枚举延迟执行直到这样做。因此,对于您的foreach,请将其更改为:
foreach (XElement el in officer.ToList())
ToList()
执行可枚举,其他像ToArray()
等执行。如果删除元素,它也是一个安全网。
附注,与问题分开:
由于您在foreach和新官员分支中都调用了doc.Save()
,因此将保存放在方法的底部作为最后发生的事情。
答案 1 :(得分:0)
除了@Chuck Savage提供的解决方案之外,如果每位官员都有唯一的ID,您可以考虑进行一些更改: 1你可以回单军官。这样你可以避免运行foreach代码块。 2检查官员是否存在更新,否则创建。无需设置update true和false。