Search code examples
c#xmllinq-to-xmlxelement

How can I get a node from an XML document based on its attribute value and into an XElement object?


I need to inject some XML into a pre-existing XML file under a certain node. Here is the code I have to create my XML:

//Define the nodes
XElement dataItemNode = new XElement("DataItem");
XElement setterNodeDisplayName = new XElement("Setter");
XElement setterNodeOU = new XElement("Setter");

//Create the tree with the nodes
dataItemNode.Add(setterNodeDisplayName);
dataItemNode.Add(setterNodeOU);

//Define the attributes
XAttribute nameAttrib = new XAttribute("Name", "OrganizationalUnits");
XAttribute displayNameAttrib = new XAttribute("Property", "DisplayName");
XAttribute ouAttrib = new XAttribute("Property", "OU");

//Attach the attributes to the nodes
setterNodeDisplayName.Add(displayNameAttrib);
setterNodeOU.Add(ouAttrib);

//Set the values for each node
setterNodeDisplayName.SetValue("TESTING DISPLAY NAME");
setterNodeOU.SetValue("OU=funky-butt,OU=super,OU=duper,OU=TMI,DC=rompa-room,DC=pbs,DC=com");

Here is the code I have so far to load up the XML document and try to get the node that I need to insert my XML under:

//Load up the UDI Wizard XML file
XDocument udiXML = XDocument.Load("UDIWizard_Config.xml");

//Get the node that I need to append to and then append my XML to it
XElement ouNode = THIS IS WHAT I DONT KNOW HOW TO DO
ouNode.Add(dataItemNode);

Here is the XML from the existing document I am trying to work with:

<Data Name="OrganizationalUnits">
        <DataItem>
          <Setter Property="DisplayName">TESTING DISPLAY NAME</Setter>
          <Setter Property="OU">OU=funky-butt,OU=super,OU=duper,OU=TMI,DC=rompa-room,DC=pbs,DC=com</Setter>
        </DataItem>

I have multiple nodes that with the name of "Data", but I need to get the node that is , and I don't know how. Just learning how to use XML with C#.

Thank you.


Solution

  • This will get the first Data node with Name attribute matching OrganizationalUnits:

    var ouNode = udiXML
        .Descendants("Data")
        .Where(n => n.Attribute("Name") != null)
        .Where(n => n.Attribute("Name").Value == "OrganizationalUnits")
        .First();
    

    If your document might contain Data nodes without Name attribute, extra check for null might be necessary.

    Note that you can achieve the same result with XPath (this will select root Data node, you can get DataItem node using Element method):

    var ouNode = udiXML.XPathSelectElement("//Data[@Name = 'OrganizationalUnits']");