mixed up attributes and elements in xml - c#

I need to create an xml the below structure.
<ipaddress> "10.10.10.10" </ipaddress>
<PipeId pid = "4598702C-691E">testvalue</PipeId> --how to display this?
<name> "testname" </name>
But I am really confused about the second line in the xml. How can it be displayed?
I tried below code..but don't know how to get the second line into xml..
new XElement("StartElement",
new XAttribute("TestAtt", "some & value"),
new XElement("ipaddress", "10.10.10.10"),
new XElement("name", "testname")));

If you're just trying to build that element, you want:
new XElement("PipeId", // Name of the element
new XAttribute("pid", "4598702C-691E"), // Attribute of the element
"testvalue") // Text content of the element

Related

add elements multiple values in XDocument C#

I want to add a section with tag name called properties, and have one item value called property with multiple value, like node name, value
org xml file is like this
<testsuites>
<testsuite>
blah blah
</testsuite>
</testsuites>
After add, i want it show like this
<testsuites>
<testsuite>
<properties>
<property name="name" "value"="desirevalue"/>
</properties>
blah blah
</testsuite>
</testsuites>
The code that i wrote has some problems, it actually create two line of property, but i want them as one line. How should i update my code? Also seems last two line has problems. i get "object reference not set to an instance of an object" error
XDocument doc = XDocument.Load(fileOfReportInXML);
XElement root= new XElement("properties");
root.Add(new XElement("property", "name= node"));
root.Add(new XElement("property","value=desirevalue"));
doc.Element("testsuite").Add(root);
doc.Save(fileOfReportInXML);
Try following code:
//Load XML file
XDocument doc = XDocument.Load(fileOfReportInXML);
Edit: Add element to the first element of your xdocument
doc.Root.Elements("testsuite").First().Add(new XElement("properties", new XElement("property", new XAttribute("name", "name"), new XAttribute("value", "desirevalue"))));
if you want to add new elements to all your testsuite elements:
foreach (var element in doc.Root.Elements("testsuite"))
{
//Skip adding element if element already exists
if (element.HasElements && element.Element("properties") != null) continue;
element.Add(new XElement("properties", new XElement("property", new XAttribute("name", "name"), new XAttribute("value", "desirevalue"))));
}
Save the XML document
//Save XML file
doc.Save(fileOfReportInXML);

Auto increment ID value in xml file

I want to add a new node to my xml file, but also, i would like to add id value in it, but incremented by 1 from the last value. Here is my XML:
<users>
<user>
<id>1</id>
<name>Name1</name>
<surname>Surname1</surname>
<weight>78</weight>
<height>180</height>
</user>
<user>
<id>2</id>
<name>Name2</name>
<surname>Surname2</surname>
<weight>84</weight>
<height>180</height>
</user>
</users>
And here is my code so far (for adding a new node):
XmlNode node = xmlDoc.SelectSingleNode("/users/user");
XmlNode newNode = xmlDoc.ImportNode(node, true);
xmlDoc.DocumentElement.AppendChild(newNode);
xmlDoc.SelectSingleNode("users/user/id").InnerText = ; // <-- ??
xmlDoc.SelectSingleNode("users/user/name").InnerText = nameBox.Text;
xmlDoc.SelectSingleNode("users/user/surname").InnerText = surnameBox.Text;
xmlDoc.SelectSingleNode("users/user/weight").InnerText = Convert.ToString(weightUpDown.Value);
xmlDoc.SelectSingleNode("users/user/height").InnerText = Convert.ToString(heightUpDown.Value);
I am using winforms in C#, in this case get the value from the text boxes and UpDown lists.
How can I do it in c#?
You can use LINQ to XML for that.First get the current element count, then insert a new element like this:
var xDoc = XDocument.Load("path");
var count = xDoc.Descendants("user").Count();
var newUser = new XElement("user",
new XElement("id", count+1),
new XElement("name", nameBox.Text),
new XElement("surname", surnameBox.Text),
new XElement("weight", weightUpDown.Value),
new XElement("height", heightUpDown.Value));
xDoc.Root.Add(newUser);
xDoc.Save(path);
I would suggest you to get element count first (maybe in Form_load) then store it into a variable.By doing that you don't need to perform this query each time you want to add new item.You just need to increment the count.
You can get the max id as follows:
var maxId = xmlDoc.SelectNodes("/users/user/id")
.Cast<XmlNode>()
.Max(node => int.Parse(node.InnerText));
using the count to determine the Id may not work correctly if nodes are removed from the XML, during execution of the program.
Use Guid.NewGuid() instead to create a unique ID
I think I need some more information...
At first glance it looks like you will need to do the following:
Iterate / loop through the values in text boxes and/or UpDown Lists.
Make sure your loop has a counter variable that is created outside of the loop "int counter = 1".
For each item you are iterating through use the counter to set the id in the xml you are generating.
Before the item goes back to looping you should then increment the counter + 1.
You will be auto-populating each node with the values anyways correct?
All you will need is to add this counter variable and you should have basically what you need.

Unable to remove root node from an xml document using linq to xml c#

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.

How to get child and grandchild elements from XML element?

So, I have an XElement, that contains multiple child elements. I can successfully declare the XElement, and write it to a file:
Test.project:
<?xml version="1.0" encoding="utf-8"?>
<project>
<child>
<grand-child1>
<great-grand-child1>Hello There!</great-grand-child1>
<great-grand-child2>Hello World!</great-grand-child2>
</grand-child1>
<grand-child2>Testing 123...</grand-child2>
</child>
</project>
Then I'm trying to read from the file. I searched for ways to get child and grand-child nodes, and found I can use XElement.XPathSelectElement(). The problem is, Visual C# doesn't recognize XPathSelectElement as a method for an XElement. I've searched for usage examples for the method, and they all say to use XElement.XPathSelectElement.
For example, I tried:
x_el = new XElement("project",
new XElement("child",
new XElement("grand-child", "Hello World!")
);
string get_string = x_el.XPathSelectElement("child/grand-child");
...but XPathSelectElement is not recognized. What am I doing wrong?
You need to add System.Xml.XPath namespace as well
like
using System.Xml.XPath;
after that try below
x_el = new XElement("project",
new XElement("child",
new XElement("grand-child", "Hello World!")
));
// XPathSelectElement method return XElement not string , use var or XElement
XElement element = x_el.XPathSelectElement("child/grand-child");
string get_string = element.ToString()
Or
var get_string = x_el.XPathSelectElement("child/grand-child").ToString();

How to get just the root element from Xelement

I have the following XElement:
<Assembly name="3">
<Component name="2" />
</Assembly>
I would like to get just the root element. <Assembly name="3"> I cant see any method which suits for me.
XElement.????? I cant find XElement.Root;
Does any clue?
You can try this in VB.NET
Dim elm as XElment = XElement.Parse(<Assembly name="3">
<Component name="2" />
</Assembly>)
Dim strName as string
strName = elm.AncestorsAndSelf.First.Name
Code in C#
XElement elm = XElement.Parse("<Assembly name='3'><Component name='2' /></Assembly>");
string name =elm.AncestorsAndSelf().First().Name;
You can get the root element this way :
XDocument.Root
Here is an example of implementation :
XDocument doc = new XDocument(
new XComment("This is a comment."),
new XElement("Pubs",
new XElement("Book",
new XElement("Title", "Artifacts of Roman Civilization"),
new XElement("Author", "Moreno, Jordao")
),
new XElement("Book",
new XElement("Title", "Midieval Tools and Implements"),
new XElement("Author", "Gazit, Inbar")
)
),
new XComment("This is another comment.")
);
Console.WriteLine(doc.Root.Name.ToString());
link : http://msdn.microsoft.com/en-us/library/system.xml.linq.xdocument.root.aspx
You could call RemoveNodes on it... create a copy first if you need to preserve the original content for other reasons.
It's not really clear what you're trying to do with this. The element logically contains all its children - there's no concept of XElement.Root because an element "is itself". RemoveNodes will remove all the child nodes, but if you just want to get the name of the element, or its attributes, you can do that without changing the structure at all.
Copy the name & attributes to a new element;
var root = new XElement(el.Name, el.Attributes());

Categories

Resources