Question

I am new to XML files and how to manage them. This is for a web app I am writing (aspx).

At the present time I am able to find the first instance of a node and add an item to it with the following code:

xmlClone.Element("PCs").Element("PC").Element("pc_hwStatus").AddAfterSelf(new XElement("user_name", txt_v0_nombre.Text));

What I really want is to add ("user_name", txt_v0_nombre.Text) to a node in particular, not the first one. The content of my XML file is:

<PCs> 
<PC> 
    <pc_name>esc01</pc_name> 
    <pc_ip>10.10.10.10</pc_ip>
    <pc_hwStatus>Working</pc_hwStatus>
 </PC> 
 <PC> 
    <pc_name>esc02</pc_name>
    <pc_ip>10.10.10.11</pc_ip> 
    <pc_hwStatus>Under Maintenance</pc_hwStatus>
 </PC>
 </PCs>

The decision of what node to update is made selecting an item from a dropdown list (the PC name).

With my current code, the new item is always added as last line of node with "pc_ name = esc01". I want to be able to added it to esc02 or esc03 and so on... How can this be accomplished? (Using xdocument)

Était-ce utile?

La solution

If I understand you correctly, what you are looking for is the FirstOrDefault extension method. In there specify which node you are wanting, in this case a string from your dropdown box, which can be passed in. So to get the first node:

var pc = xmlClone.Element("PCs").Elements("PC").FirstOrDefault(e => e.Element("pc_name").Value == "esc01");

Now you have this in your XElement:

<PC> 
    <pc_name>esc01</pc_name> 
    <pc_ip>10.10.10.10</pc_ip>
    <pc_hwStatus>Working</pc_hwStatus>
</PC> 

To get any element like that, just replace this clause:

.FirstOrDefault(e => e.Element("pc_name").Value == "esc01");

with this one

.FirstOrDefault(e => e.Element("pc_name").Value == desiredPC);

where desiredPC is the value of the xml node: pc_name.

Now to add your data just call the plain old Add method:

pc.Add(new XElement("user_name", txt_v0_nombre.Text);

That should do the trick for you.

Autres conseils

Here's a solution that uses LINQ query syntax with LINQ to XML:

XDocument document = XDocument.Parse(xmlContent);
string pcName = "esc02";

IEnumerable<XElement> query =
    from pc in document.Element("PCs").Elements("PC")
    where pc.Element("pc_name").Value.Equals(pcName)
    select pc;

XElement xe = query.FirstOrDefault();

if (xe != null)
{
    xe.Add(new XElement("user_name", "DMS"));
}

I have incorporated your sample data and this query into a demonstration program. Please see below for the output from the demonstration program followed by the program itself.

Expected Output

<PC>
  <pc_name>esc02</pc_name>
  <pc_ip>10.10.10.11</pc_ip>
  <pc_hwStatus>Under Maintenance</pc_hwStatus>
  <user_name>DMS</user_name>
</PC>

Demonstration Program

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

namespace LinqToXmlDemo
{
    public class Program
    {
        public static void Main(string[] args)
        {
            string xmlContent = GetXml();
            XDocument document = XDocument.Parse(xmlContent);

            XElement xe = FindPCName(document, "esc02");

            if (xe != null)
            {
                xe.Add(new XElement("user_name", "DMS"));
                Console.WriteLine(xe);
            }
            else
            {
                Console.WriteLine("Query returned no results.");
            }
        }

        private static XElement FindPCName(XDocument document, String pcName)
        {
            IEnumerable<XElement> query =
                from pc in document.Element("PCs").Elements("PC")
                where pc.Element("pc_name").Value.Equals(pcName)
                select pc;

            return query.FirstOrDefault();
        }

        private static String GetXml()
        {
            return
                @"<?xml version='1.0' encoding='utf-8'?>
                  <PCs> 
                    <PC> 
                      <pc_name>esc01</pc_name> 
                      <pc_ip>10.10.10.10</pc_ip>
                      <pc_hwStatus>Working</pc_hwStatus>
                    </PC> 
                    <PC> 
                      <pc_name>esc02</pc_name>
                      <pc_ip>10.10.10.11</pc_ip> 
                      <pc_hwStatus>Under Maintenance</pc_hwStatus>
                    </PC>
                  </PCs>";
        }        
    }
}

Method .Element returns the first element with the specified name.

You can get the whole list with method .Elements, and iterate this list to find the one you are looking for.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top