设置特定xmlNode的值

时间:2017-04-11 14:13:33

标签: c# .net xml

目前我正在使用c#windows窗体应用程序,但我遇到以下问题:

我有下面列出的xml:

  <new>
    <Company></Company>
    <DateTime></DateTime>
    <Message></Message>
    <Status><Status>
  </new>
  <new>
    <Company></Company>
    <DateTime></DateTime>
    <Message></Message>
    <Status><Status>
  </new>
  <new>
    <Company></Company>
    <DateTime></DateTime>
    <Message></Message>
    <Status><Status>
  </new>
  <new>
    <Company></Company>
    <DateTime></DateTime>
    <Message></Message>
    <Status><Status>
  </new>
  <new>
    <Company></Company>
    <DateTime></DateTime>
    <Message></Message>
    <Status><Status>
  </new>

我得到的数据是这样的:

    XDocument doc = XDocument.Load(Globals.pathNotifFile);
    var notifDateTime = doc.Descendants("DateTime");
    var message = doc.Descendants("Message");
    var company = doc.Descendants("Company");
    var sendStatus = doc.Descendants("Status");

    var dateTimeCollection = new List<String>();
    var messageCollection = new List<String>();
    var companyCollection = new List<String>();
    var statusCollection = new List<String>();

    foreach (var dateTimeOfNotification in notifDateTime)
    {
        dateTimeCollection.Add(dateTimeOfNotification.Value);
    }

    foreach (var messages in message)
    {
        messageCollection.Add(messages.Value);
    }

    foreach (var companys in company)
    {
        companyCollection.Add(companys.Value);
    }

    foreach (var isSent in sendStatus)
    {
        statusCollection.Add(isSent.Value);
    }

    return Tuple.Create(dateTimeCollection, messageCollection, companyCollection, statusCollection);

我正在使用xml文件的数据

        Tuple<List<String>, List<String>, List<String>, List<String>> t = GetDataFromFile();
        List<String> dateTimeCollection = t.Item1;
        List<String> messageCollection = t.Item2;
        List<String> companyCollection = t.Item3;
        List<String> statusCollection = t.Item4;

        foreach (var notifDateTime in dateTimeCollection)
        {
            int index = dateTimeCollection.IndexOf(notifDateTime);
            if (Int32.Parse(statusCollection[index]) == 1 || statusCollection[index] == string.Empty)
            {
                if (notifDateTime != string.Empty)
                {
                    if (Convert.ToDateTime(notifDateTime) == DateTime.Now)
                    {
                        SendMessageToUser(messageCollection[index], companyCollection[index]);
                    }
                }
            }
        }

之后在SendMessageToUser中我发送消息并得到响应1,2或3,但我的问题是获取确切的节点,我必须写入状态。我用来写状态的函数是:

    XmlDocument doc = new XmlDocument();
    doc.LoadXml(Globals.pathNotifFile);

    XmlNode commentsElement = doc.SelectSingleNode("Status");
    commentsElement.InnerText = status.ToString();

    doc.Save(Globals.pathNotifFile);

所以在 doc.SelectSingleNode((“Status”))中,我必须放置所选节点并进行更新。任何想法我怎么做

3 个答案:

答案 0 :(得分:1)

我会解析下面的代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;

namespace ConsoleApplication49
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            XDocument doc = XDocument.Load(FILENAME);

            var results = doc.Descendants("new").Select(x => new {
                company = (string)x.Element("Company"),
                dateTime = (DateTime)x.Element("DateTime"),
                message = (string)x.Element("Message"),
                status = (string)x.Element("Status")
            }).ToList();
        }

    }
}

答案 1 :(得分:1)

首先,您应该将解析文件的方式更改为:

Convert.ToXXX(Object, IFormatProvider)

然后遍历解析后的树并更新相关var newsDatas = xdoc.Descendants("new") .Select( element => new { Company = element.Element("Company").Value, DateTime = element.Element("DateTime").Value, Message = element.Element("Message").Value, Node = element });

中的Status
Node

最后,保存XDocument:

foreach (var newsData in newsDatas) 
{
    // .. You logic
    SendMessageToUser(newsData.Message, newsData.Company);

    string status = ....;
    newsData.Node.Element("Status").Value = status;
}

答案 2 :(得分:0)

只是直接回答您的问题而不进行任何代码修改 - 如果要使用xpath选择特定节点,也可以这样做:

doc.SelectSingleNode("//new[1]/Status");

当然代替“1”你可以放任何你想要的索引(它们不是从零开始)

编辑:正如您在评论中所说,您没有考虑序列化/反序列化,我强烈建议您尝试使用它。为了让您按照以下方式定义数据:

[Serializable]
public class root
{
    [System.Xml.Serialization.XmlElementAttribute("new")]
    public Node[] @new { get; set; }
}

[Serializable]
public class Node
{
    public string Status { get; set; }
    public string Company { get; set; }
    //other properties
}

现在你可以这样做:

static void Main(string[] args)
{
    var data = Deserialize();
    //do your logic on normal object
    Serialize(data);


}

static root Deserialize()
{
    using (var file = File.Open("test.txt", FileMode.Open))
    {
        XmlRootAttribute xRoot = new XmlRootAttribute();
        xRoot.ElementName = "root";
        xRoot.IsNullable = true;
        var xmlSerializer = new XmlSerializer(typeof(root), xRoot);
        return (root)xmlSerializer.Deserialize(file);
    }
}

static void Serialize(root data)
{
    using (var file = File.Create("result.txt"))
    {
        var xmlSerializer = new XmlSerializer(typeof(root));
        xmlSerializer.Serialize(file, data);
    }
}

只是一个例子,当然这是一个很大的话题,你可以在SO和其他网站上找到很多例子