仅在具有指定值时编辑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");

仅在具有指定值时编辑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相同的代理的引用。