質問

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)

役に立ちましたか?

解決

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.

他のヒント

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.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top