I have a xml file from which only specific nodes have to be removed. The node name will be given as input from the user. How to remove the specific nodes which have requested from the user?
<Customers>
<Customer>
<id>michle</id>
<address>newjersy</address>
</Customer>
<Customer>
<id>ann</id>
<address>canada</address>
</Customer>
</Customers>
I have tried
var customer = new XElement("customer",
from o in customers
select
new XElement("id", id),
new XElement("address", address)
);
Customer will contain a new node
<Customer>
<id>ann</id>
<address>canada</address>
</Customer>
doc.Element("customers").Elements(customer).ToList().Remove();
but this is not working. How can I remove the element from the xml?
Tom,
Try this...
private static void RemoveNode(string sID)
{
XDocument doc = XDocument.Load(#"D:\\Projects\\RemoveNode.xml");
var v = from n in doc.Descendants("Customer")
where n.Element("id").Value == sID
select n;
v.Remove();
doc.Save(#"D:\\Projects\\RemoveNode.xml");
}
This removed one node when I called it using
RemoveNode("michle");
Hope this helps.
Your main mistake is that you are creating new nodes that not attached with the source document instead of retrieving existed nodes from it.
You can use article "Removing Elements, Attributes, and Nodes from an XML Tree" on MSDN as a guideline to manipulating XML data.
For example, use XNode.Remove() method to delete one node from the tree or Extensions.Remove<T>(this IEnumerable<T> source) where T : XNode to remove every node in the source collection of nodes:
doc.Descendants("Customer")
.Where(x => x.Element("id").Value == id)
.Remove();
But you also need to save document via Save method after that for commit your changes:
doc.Save();
You can remove this way based on id
xdoc.Descendants("Customer")
.Where(x => (string)x.Element("id") == "michle")
.Remove();
Related
I am using C# .
I have an xml node with child nodes as follows :
<PriceID>32</PriceID>
<Store_1> 344</Store_1>
<Store_32> 343 </Store_32>
I would like to select all nodes that start with Store
Is there a way I can do it ?
I know there is a way to select nodes with specific names ..
XmlNodeList xnList = quote.SelectNodes("Store_1");
Does anyone know what will help me ?
You can use Linq2Xml
var xDoc = XDocument.Parse(xmlstring);
var stores = xDoc.Descendants()
.Where(d => d.Name.LocalName.StartsWith("Store"))
.ToList();
Actullay, I need to get all elements except root node from first xml document and so that I could insert them as child nodes to an element(that has same name as a previous doc's root name) in a new document.
So I have tried various ways to achieve it, one of them is removing the root node of first and then trying to add elements to a new one's as given below:
I have tried the following but could not achieve it.
XDocument testDoc = XDocument.Parse(Mydocument);
testDoc.Descendants().Where(e => e.Name.LocalName == "rootName").Select(m=>m).Single().Remove();
var resultDoc = testDoc;
The above code is giving me an empty "{}" result.
my xml document looks something like the below one's:
<rootName xsi:schemaLocation="" xmlns:xsi="" xmlns="">
<main>
<child>
</child>
<anotherchild>
</anotherchild>
</main>
</rootName>
And another way is getting all the elements of first document as the following:
var resultDoc = testDoc.Descendants(ns + "rootName").Elements();
the above statement is giving me the list of elements in the "testDoc" which
I need to do something like below, I am clueless:
<AnotherDocument xsi:schemaLocation="" xmlns:xsi="" xmlns="">
<firstNode>
<rootName>
<main>
<child>
</child>
<anotherchild>
</anotherchild>
</main>
</rootName>
</firstNode>
Please let me know how to insert those elements in a new document as above if I am correct else let me know the way to resolve this issue.
Thanks in advance.
You can replace content of rootName element in another document with elements from first document root:
var xDoc = XDocument.Parse(Mydocument);
var anotherXDoc = XDocument.Load("anotherdata.xml");
XNamespace ns = "http://..."; // your xml namespance
var rootName = anotherXDoc.Descendants(ns + "rootName").First();
rootName.ReplaceNodes(xDoc.Root.Elements());
By this page_nodes gets all nodes now you can used all node by for each loop
var page_nodes = from p in xdoc.Descendants.Where(e => e.Name.LocalName == "rootName").Select(m=>m).Single().Remove() select p;
foreach (var page_node in page_nodes)
{
//Do stuff
}
Wouldn't removing a root node, remove all its child nodes as well? The result you are getting is to be expected I think. You should probably get all the children of the root and copy them to your new document.
Basically what I am trying to do is remove a VSLOC from the list. I don't want to remove everything that belongs to it.
<?xml version="1.0"?>
<GarageNumbers>
<G554>
<id>G554</id>
<VSLOC>V002</VSLOC>
<VSLOC>V003</VSLOC>
<VSLOC>V002</VSLOC>
</G554>
<G566>
<id>G566</id>
<VSLOC>V002</VSLOC>
<VSLOC>V003</VSLOC>
<VSLOC>V002</VSLOC>
</G566>
<G572>
<id>G572</id>
<VSLOC>V001</VSLOC>
<VSLOC>V002</VSLOC>
</G572>
</GarageNumbers>
So, what I have setup is a combobox that I select a G# from which brings up all the VSLOC associated with it in a Listbox. What I need to do is to select a item from the list box and remove the line from the listbox and from the xml document using a button. I have all this setup but when I hit the button it deletes G554 and all the elements with in.
So if I want to select V002 from the list in G554 I want it to just remove that VSLOC with that innertext.
XmlDocument xDoc = new XmlDocument();
xDoc.Load(Application.StartupPath + "/xmlData.xml");
foreach (XmlNode xNode in xDoc.SelectNodes("GarageNumbers/G554"))
if (xNode.SelectSingleNode("VSLOC").InnerText == "V002")
xNode.ParentNode.RemoveChild(xNode);
xDoc.Save(Application.StartupPath + "/xmlData.xml");
You should be able to drill down to the desired elements then remove them. For example, assuming your XML is in an XElement, this approach would work:
string targetCategory = "G554";
string vsloc = "V002";
xml.Element(targetCategory)
.Elements("VSLOC")
.Where(e => e.Value == vsloc)
.Remove();
If you're using an XDocument then add the Root property: xml.Root
var xDoc = XDocument.Load(fname);
var node = xDoc.Descendants("VSLOC")
.Where(e => (string)e.Parent.Element("id") == "G554")
.FirstOrDefault();
if (node != null) node.Remove();
xDoc.Save(fname);
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.
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']");
Here is my XML :
<?xml version="1.0" encoding="utf-8" ?>
<Selection>
<ID>1</ID>
<Nom>Name 1</Nom>
<DateReference>0</DateReference>
<PrefixeMedia>Department</PrefixeMedia>
<FormatExport>1630</FormatExport>
<TraceAuto>Oui</TraceAuto>
<SubID></SubID>
</Selection>
<Selection>
<ID>2</ID>
<Nom>Name 1</Nom>
<DateReference>0</DateReference>
<PrefixeMedia>Department</PrefixeMedia>
<FormatExport>1630</FormatExport>
<TraceAuto>1</TraceAuto>
<SubID>1</SubID>
</Selection>
My problem is I would like to modify for example the node content of <Nom>Name 1</Nom> which is located in <Selection></Selection> which have <ID>1</ID> (Search by ID)
I'm using XElement and XDocument to do simple search but I need some help to solve this problem above. (Developpment on SilverLight
Best Regards.
Another way to do this is using XmlDocument:
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(#"\path\to\file.xml");
// Select the <nom> node under the <Selection> node which has <ID> of '1'
XmlNode name = xmlDoc.SelectSingleNode("/Selection[ID='1']/Nom");
// Modify the value of the node
name.InnerText = "New Name 1";
// Save the XML document
xmlDoc.Save(#"\path\to\file.xml");
If you don't know how to get at the correct <Nom> node to update, the trick is to first select a <Selection> node that contains the correct <ID> node, then you can get that <Nom> node.
Something like:
XElement tree = <your XML>;
XElement selection = tree.Descendants("Selection")
.Where(n => n.Descendants("ID").First().Value == "1") // search for <ID>1</ID>
.FirstOrDefault();
if (selection != null)
{
XElement nom = selection.Descendants("Nom").First();
nom.Value = "Name one";
}
Note 1: By using Descendants("ID").First() I expect every Selection node to contain an ID node.
Note 2: And every Selection node contains a Nom node
Note 3: Now you still have to store the whole XML, if that's what you need.