仅在具有指定值时编辑XML节点内部文本
本文关键字:XML 编辑 节点 内部 文本 | 更新日期: 2023-09-27 17:49:47
你好,我需要你的超级帮助。我不太擅长c#,我在这上面堆了大约6个小时。所以如果有人知道,请帮助我。Thx
我有这样的Xml
<COREBASE>
<AGENT>
<AGENT_INDEX>1</AGENT_INDEX>
<AGENT_PORTER_INDEX>
</AGENT_PORTER_INDEX>
<AGENT_NAME>John</AGENT_NAME>
<AGENT_SURNAME>Smith</AGENT_SURNAME>
<AGENT_MOBILE_NUMBER>777777777</AGENT_MOBILE_NUMBER>
</AGENT>
<AGENT>
<AGENT_INDEX>2</AGENT_INDEX>
<AGENT_PORTER_INDEX>1
</AGENT_PORTER_INDEX>
<AGENT_NAME>Charles</AGENT_NAME>
<AGENT_SURNAME>Bukowski</AGENT_SURNAME>
<AGENT_MOBILE_NUMBER>99999999</AGENT_MOBILE_NUMBER>
</AGENT>
</COREBASE>
我需要选择代理的索引在windows窗体组合框,然后编辑和保存他的属性到xml。我发现如何编辑和保存它,但我不知道为什么,但它保存到第一个代理和覆盖他的属性在XML中,而不是在选定的一个…: - (
如果有任何帮助,我都很高兴。
private void buttonEditAgent_Click(object sender, EventArgs e)
{
XmlDocument AgentBaseEdit = new XmlDocument();
AgentBaseEdit.Load("AgentBase.xml");
XDocument AgentBase = XDocument.Load("AgentBase.xml");
var all = from a in AgentBase.Descendants("AGENT")
select new
{
agentI = a.Element("AGENT_INDEX").Value,
porterI = a.Element("AGENT_PORTER_INDEX").Value,
agentN = a.Element("AGENT_NAME").Value,
agentS = a.Element("AGENT_SURNAME").Value,
agentM = a.Element("AGENT_MOBILE_NUMBER").Value,
};
foreach (var a in all)
{
if ("" == textBoxEditAgentIndex.Text.ToString())
{
MessageBox.Show("You must fill Agent Index field !!", "WARNING");
}
else
{
// AgentBaseEdit.SelectSingleNode("COREBASE/AGENT/AGENT_INDEX").InnerText == textBoxEditAgentIndex.Text
if (a.agentI == textBoxEditAgentIndex.Text.ToString())
{
AgentBaseEdit.SelectSingleNode("COREBASE/AGENT/AGENT_INDEX").InnerText = textBoxEditAgentIndex.Text;
AgentBaseEdit.SelectSingleNode("COREBASE/AGENT/AGENT_PORTER_INDEX").InnerText = textBoxEditAgentPorterIndex.Text;
AgentBaseEdit.SelectSingleNode("COREBASE/AGENT/AGENT_NAME").InnerText = textBoxEditAgentName.Text;
AgentBaseEdit.SelectSingleNode("COREBASE/AGENT/AGENT_SURNAME").InnerText = textBoxEditAgentSurname.Text;
AgentBaseEdit.SelectSingleNode("COREBASE/AGENT/AGENT_MOBILE_NUMBER").InnerText = textBoxEditAgentMobile.Text;
AgentBaseEdit.Save("AgentBase.xml");
ClearEditAgentTxtBoxes();
}
}
}
}
我在正确的方式,但我没有看到门或我是完全错误的?谢谢所有人。巫女
好的,我试过这样做,但是它没有改变内部文本
string agentIndex = comboBoxEditAgentI.SelectedItem.ToString();
XmlDocument AgentBaseEdit = new XmlDocument();
AgentBaseEdit.Load("AgentBase.xml");
XDocument AgentBase = XDocument.Load("AgentBase.xml");
var xElemAgent = AgentBase.Descendants("AGENT")
.First(a => a.Element("AGENT_INDEX").Value == agentIndex);
xElemAgent.Element("AGENT_MOBILE_NUMBER").Value = textBoxEditAgentMobile.Text;
xElemAgent.Element("AGENT_SURNAME").Value = textBoxEditAgentSurname.Text;
AgentBaseEdit.Save("AgentBase.xml");
如果使用Linq2Xml会更容易。
int agentIndex = 2;
XDocument xDoc = XDocument.Load(filename);
var xElemAgent = xDoc.Descendants("AGENT")
.First(a => a.Element("AGENT_INDEX").Value == agentIndex.ToString());
//or
//var xElemAgent = xDoc.XPathSelectElement(String.Format("//AGENT[AGENT_INDEX='{0}']",agentIndex));
xElemAgent.Element("AGENT_MOBILE_NUMBER").Value = "5555555";
xDoc.Save(fileName)
PS: namespaces: System.Xml.XPath
System.Xml.Linq
这不起作用,因为您在每个循环中显式地选择了第一个代理
AgentBaseEdit.SelectSingleNode("COREBASE/AGENT/...")
但是您可以通过在同一个xml文档中读取和更改来更容易地做到这一点。我只是更改代理名称,并将其替换为"测试1","测试2",…
XDocument AgentBase = XDocument.Load("AgentBase.xml");
int i = 0;
foreach (XElement el in AgentBase.Descendants("AGENT")) {
el.Element("AGENT_NAME").Value = "test " + ++i;
// ...
}
AgentBase.Save("AgentBase.xml");
但是,我建议您将涉及XML处理的逻辑与表单分开。首先创建一个Agent类
public class Agent
{
public string Index { get; set; }
public string PorterIndex { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
public string Mobile { get; set; }
}
然后创建一个接口,定义代理存储库所需的功能。这个接口的优点是,以后切换到另一种存储库(如关系数据库)会更容易。
public interface IAgentRepository
{
IList<Agent> LoadAgents();
void Save(IEnumerable<Agent> agents);
}
然后创建一个处理代理的类。这里有一个建议:
public class AgentXmlRepository : IAgentRepository
{
private string _xmlAgentsFile;
public AgentXmlRepository(string xmlAgentsFile)
{
_xmlAgentsFile = xmlAgentsFile;
}
public IList<Agent> LoadAgents()
{
XDocument AgentBase = XDocument.Load(_xmlAgentsFile);
var agents = new List<Agent>();
foreach (XElement el in AgentBase.Descendants("AGENT")) {
var agent = new Agent {
Index = el.Element("AGENT_INDEX").Value,
PorterIndex = el.Element("AGENT_PORTER_INDEX").Value,
Name = el.Element("AGENT_NAME").Value,
Surname = el.Element("AGENT_SURNAME").Value,
Mobile = el.Element("AGENT_MOBILE_NUMBER").Value
};
agents.Add(agent);
}
return agents;
}
public void Save(IEnumerable<Agent> agents)
{
var xDocument = new XDocument(
new XDeclaration("1.0", "utf-8", null),
new XElement("COREBASE",
agents.Select(a =>
new XElement("AGENT",
new XElement("AGENT_INDEX", a.Index),
new XElement("AGENT_PORTER_INDEX", a.PorterIndex),
new XElement("AGENT_NAME", a.Name),
new XElement("AGENT_SURNAME", a.Surname),
new XElement("AGENT_MOBILE_NUMBER", a.Mobile)
)
)
)
);
xDocument.Save(_xmlAgentsFile);
}
}
表单现在可以专注于编辑逻辑。如果在表单构造函数中注入存储库,表单甚至不需要知道使用哪种存储库(因为表单构造函数必须声明类型为IAgentRepository
的参数):
var myAgentForm = new AgentForm(new AgentXmlRepository("AgentBase.xml"));
myAgentForm.Show();
更新# 2
请注意,您不能更改XML文件中的单个项。您必须加载所有代理,进行编辑,然后重写整个文件,即使您只编辑了一个代理。
为此,您可以使用我的LoadAgents
方法,然后从返回的列表中选择一个代理,编辑代理,最后使用我的Save
方法将代理列表写回文件。您可以使用LINQ:
Agent a = agents
.Where(a => a.Index == x)
.FirstOrDefault();
如果所需索引的代理不存在,则返回null
。由于Agent
是一个引用类型,您不必将其写回列表。该列表保留了对与变量a
相同的代理的引用。