仅在具有特定值的情况下编辑XML节点innertext

时间:2012-12-29 18:10:08

标签: c# xml edit editing

你好我需要你的超级帮助。 我不擅长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");

2 个答案:

答案 0 :(得分:0)

如果你使用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:名称空间:System.Xml.XPath System.Xml.Linq

答案 1 :(得分:0)

它不起作用,因为您在每个循环中明确选择第一个代理

AgentBaseEdit.SelectSingleNode("COREBASE/AGENT/...")

但是通过阅读和更改相同的xml文档,您可以更轻松地完成这项工作。我只是更改代理名称并将其替换为“test 1”,“test 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保持对同一代理的引用。

相关问题