Найдите атрибут, который содержит строку ceratin и измените его значение в c # с помощью LINQ. - PullRequest
3 голосов
/ 01 сентября 2010

Я пытаюсь найти первый атрибут в XML-файле, который содержит в себе строку «name» (без учета регистра), а затем изменить его значение.

Вот пример моего xmls

//XML 1
<CtApproachTypes  
 DataclassId="1992A9CE-B048-4676-BFD4-FD81F1A65401"  
 EntityId="1992A9CE-B048-4676-BFD4-FD81F1A65401"  
 Name="PAR"  
 Remark="No Remarks"></CT_ApproachTypes> 

//XML 2
<MiMissions  
 DataclassId="C196A66B-4FA1-461C-9EEF-95A4F2085051"  
 EntityId="C196A66B-4FA1-461C-9EEF-95A4F2085051"  
 MissionName="Standard" 
 Visib="1"></MiMissions> 

//XML 3
<StSituations  
 DataclassId="679FAC3C-C9EF-41FD-9A13-957915605F01"  
 EntityId="679FAC3C-C9EF-41FD-9A13-957915605F01"  
 Sname="Standard"  
 Status="C"  
 Template="1"></StSituations> 

Я хочу изменить значения «Имя», «Имя миссии», «Имя» и вывести их на консоль

EDIT вот мой код

        public void updateXmlFile(string strFileName)
    {
        try
        {
            XmlDocument doc = new XmlDocument();
            doc.Load(strFileName);

            string newValue = GetUniqueKey();

            XmlNodeList list = doc.SelectNodes("@*"); 
            IEnumerable<XmlNode> filteredList= list.Cast<XmlNode>().Where(item=>item.Value.ToLower().Contains("name"));

            foreach (XmlNode n in filteredList)
            {
                Console.WriteLine("NODES ARE : {0}", n);
            }
                doc.Save(strFileName);

        }
        catch (XmlException xex) { Console.WriteLine(xex); }

    }

Это ничего не распечатало, и мне все еще нужно изменить исходное значение строкой newValue

Ответы [ 2 ]

2 голосов
/ 02 сентября 2010

Я бы использовал объект XDocument, потому что это легко сделать запрос с linq. Он находится в System.Xml.Linq пространстве имен и сборке.

public void updateXmlFile(string strFileName)
{
    XDocument xDoc = XDocument.Load(strFileName);

    var nameAttributes = from el in xDoc.Root.Elements()
                         from attr in el.Attributes()
                         where attr.Name.ToString().ToLower().Contains("name")
                         select attr;

    foreach (var attribute in nameAttributes)
    {
        attribute.Value = "newValue";
        Console.WriteLine("{0}: {1}", attribute.Name, attribute.Value);
    }

    xDoc.Save(strFileName);
}

Обновление

Это вывод с учетом XML в вашем примере, если он сохранен в одном файле:

Name: newValue
MissionName: newValue
Sname: newValue
1 голос
/ 01 сентября 2010

Что вы можете сделать, это сначала выбрать все атрибуты XML, а затем использовать LINQ, чтобы выбрать все атрибуты, содержащие «Имя».

XmlDocument document = new XmlDocument();
...
XmlNodeList list = document.SelectNodes("@*");
IEnumerable<XmlNode> filteredList= list.Cast<XmlNode>().Where(item=>item.Value.ToLower().Contains("name"));

Надеюсь, это направит вас в правильном направлении.

Edit:

Реда, ты был абсолютно прав, я допустил несколько ошибок. Этот код работал на моей машине ;-) Я добавил комментарии, где я изменил ваш код.

    public void updateXmlFile(string strFileName)
    {
        try
        {
            XmlDocument doc = new XmlDocument();
            doc.Load(strFileName);

            string newValue = GetUniqueKey();

            XmlNodeList list = doc.SelectNodes("//@*"); // Forgot the slashes here...
            IEnumerable<XmlNode> filteredList = list.Cast<XmlNode>().
                Where(item => item.Name.ToLower().Contains("name")); // Name property instead of Value

            foreach (XmlNode n in filteredList)
            {
                n.Value = newValue; // Setting the value.
                Console.WriteLine("FILTERED NODES ARE : {0}", n.Value);
            }

            doc.Save(strFileName);

        }
        catch (XmlException xex) { Console.WriteLine(xex); }

    }
...