XElement => Add children nodes at run time - c#

So let's assume this is what i want to achieve:
<root>
<name>AAAA</name>
<last>BBBB</last>
<children>
<child>
<name>XXX</name>
<last>TTT</last>
</child>
<child>
<name>OOO</name>
<last>PPP</last>
</child>
</children>
</root>
Not sure if using XElement is the simplest way
but this is what I have so far:
XElement x = new XElement("root",
new XElement("name", "AAA"),
new XElement("last", "BBB"));
Now I have to add the "children" based on some data i have.
There could be 1,2,3,4 ...
so I need to iterate thru my list to get every single child
foreach (Children c in family)
{
x.Add(new XElement("child",
new XElement("name", "XXX"),
new XElement("last", "TTT"));
}
PROBLEM:
Doing this way I will be missing the "CHILDREN Parent node".
If I just add it before the foreach, it will be rendered as a closed node
<children/>
and that's NOT what we want.
QUESTION:
How can I add to the 1st part a parent node and as many as my list has?

Try this:
var x = new XElement("root",
new XElement("name", "AAA"),
new XElement("last", "BBB"),
new XElement("children",
from c in family
select new XElement("child",
new XElement("name", "XXX"),
new XElement("last", "TTT")
)
)
);

XElement root = new XElement("root",
new XElement("name", "AAA"),
new XElement("last", "BBB"));
XElement children = new XElement("children");
foreach (Children c in family)
{
children.Add(new XElement("child",
new XElement("name", c.Name),
new XElement("last", c.Last));
}
root.Add(children);

var children = new XElement("children");
XElement x = new XElement("root",
new XElement("name", "AAA"),
new XElement("last", "BBB"),
children);
foreach (Children c in family)
{
children.Add(new XElement("child",
new XElement("name", "XXX"),
new XElement("last", "TTT"));
}

Related

Missing the begin of the root in xml

The Code:
new XElement("Person"));
XElement items = xdoc.Root
foreach (ObservableCollection<Person> x in list)
{
XElement children = new XElement("List");
foreach (var person in x)
{
XElement person = new XElement("Person",
new XElement("Name", person.name),
new XElement("Surname", person.surn),
new XElement("City", person.city));
items.Add(person);
}
items.Add(children);
}
xdoc.Save(path);
But in XML it looks like that:
<Pepole>
<Person>
<name>d</name>
<surname>a</surname>
<city>b</city>
</Person>
**<List />**
It's missing the start of the list - please any advice how to solve it?
Its very unclear what you want. You have a collection of lists of Person objects. Do you want a separate List tag for each List or all the Person tags to be within one List tag?
Well here's both:
All in one list:
XElement items = xdoc.Root
XElement bigList= new XElement("List");
items.Add(bigList);
foreach (ObservableCollection<Person> x in list)
{
foreach (var person in x)
{
XElement person = new XElement("Person",
new XElement("Name", person.name),
new XElement("Surname", person.surn),
new XElement("City", person.city));
bigList.Add(person);
}
}
xdoc.Save(path);
Individual list for each List:
XElement items = xdoc.Root
foreach (ObservableCollection<Person> x in list)
{
XElement smallList= new XElement("List");
items.Add(smallList);
foreach (var person in x)
{
XElement person = new XElement("Person",
new XElement("Name", person.name),
new XElement("Surname", person.surn),
new XElement("City", person.city));
smallList.Add(person);
}
}
xdoc.Save(path);
It's missing the start of the list
No - it's rendering an empty List tag . You added person to the root element instead of to the children element, so it gets rendered under the root instead of under List.

How to format XDocument code to make it the most readable

I've written a method to serialize a list (containing class objects) into an xml string, but with so many nests I can't figure out how to format my code to make it the most readable. Here's the xml example:
<Text>
<Info name="example" language="en-US">example</Info>
<Info name="example" language="en-GB">example</Info>
</Text>
And here's the (most likely) terribly formatted code:
XDocument xdoc = new XDocument
(
new XElement
("Text",
Infos.Select(item =>
new XElement
("Info",
new XAttribute("name", item.Name),
new XAttribute("language", item.Language),
item.Value)
)
)
);
return xdoc.ToString();
This is a fairly short example, but it may grow in the future and as such, I'd like to make my code the most readable - how do I do that here?
I like this format
//Option 1
XDocument xdoc1 = new XDocument();
xdoc1.Add(new XElement("Text",
Infos.Select(item => new XElement("Info",
new XAttribute("name", item.Name),
new XAttribute("language", item.Language),
item.Value
)
)
));
//Option 2
XDocument xdoc2 = new XDocument();
xdoc2.Add(new XElement("Text", new object[] {
Infos.Select(item => new XElement("Info", new object[] {
new XAttribute("name", item.Name),
new XAttribute("language", item.Language),
item.Value
}))
}));

Add collection of items( xml elements) to XML doc

How to add the collection of items to XML Document ? Something I started trying, but it's wrong! I'll be grateful for the link on the Internet at a good tutorial too. Also, It is assumed that the iteration will be some elements.
Such code:
public static void Create_Interfaces()
{
XDocument Interfaces;
Interfaces = XDocument.Load("Interfaces.xml");
List<string> intf = new List<string>{"em0","em1","em2"};
foreach (var i in intf)
{
Interfaces = new XDocument(
new XElement("Interfaces",
new XElement("Interface",
new XElement("name", i),
new XElement("vlan-tagging", XElement.EmptySequence),
new XElement("unit",
new XElement("vlan-id", "10"),
new XElement("family", new XElement("inet", new XElement("address", new XElement("name", "10.10.1.23/24"))))))));
}
Interfaces.Save("Interfaces.xml");
}
Get your root element add new elements to it then save it:
var rootElement = Interfaces.Root;
foreach (var i in intf)
{
var element = new XElement("Interface",
new XElement("name", i),
new XElement("vlan-tagging", XElement.EmptySequence),
new XElement("unit",
new XElement("vlan-id", "10"),
new XElement("family",
new XElement("inet",
new XElement("address",
new XElement("name", "10.10.1.23/24"))))));
rootElement.Add(element);
}
rootElement.Save("Interfaces.xml");

Generate XML from Dictionary

I have a dictionary with key value pair. I want to write it to XML using LINQ.
I am able to create the XML document using LINQ but not sure how to read the values from dictionary & write into the XML.
Following is the example with hardcode values to generate XML, I want to ready the dictionary instead of hardcode values
XDocument doc = new XDocument(
new XDeclaration("1.0", "utf-8", "true"),
new XElement("countrylist",
new XElement("country",
new XAttribute("id", "EMP001"),
new XAttribute("name", "EMP001")
),
new XElement("country",
new XAttribute("id", "EMP001"),
new XAttribute("name", "EMP001")
)
)
);
If the id attribute is stored as dictionary key and the name as value, you can use the following
XDocument doc = new XDocument(
new XDeclaration("1.0", "utf-8", "true"),
new XElement("countrylist",
dict.Select(d => new XElement("country",
new XAttribute("id", d.Key),
new XAttribute("name", d.Value))))
);
Assuming you have a Country class with an Id and a Name and the countries are stored as values in your dictionary countries, with the id beeing the key:
XDocument xDoc = new XDocument(new XDeclaration("1.0", "utf-8", "true"));
var xCountryList = new XElement("countrylist");
foreach(var kvp in countries)
xCountryList.Add(new XElement("country",
new XAttribute("id", kvp.Key),
new XAttribute("name", kvp.Value.Name)));
Here dude with the dictionary
Dictionary<int, string> fooDictionary = new Dictionary<int, string>();
fooDictionary.Add(1, "foo");
fooDictionary.Add(2, "bar");
XDocument doc = new XDocument(
new XDeclaration("1.0", "utf-8", "true"),
new XElement("countrylist")
);
var countryList = doc.Descendants("countrylist").Single(); // Get Country List Element
foreach (var bar in fooDictionary) {
// Add values per item
countryList.Add(new XElement("country",
new XAttribute("id", bar.Key),
new XAttribute("name", bar.Value)));
}

This operation would create an incorrectly structured document

I am new to XML and tried the following but I'm getting an exception. Can someone help me?
The exception is This operation would create an incorrectly structured document
My code:
string strPath = Server.MapPath("sample.xml");
XDocument doc;
if (!System.IO.File.Exists(strPath))
{
doc = new XDocument(
new XElement("Employees",
new XElement("Employee",
new XAttribute("id", 1),
new XElement("EmpName", "XYZ"))),
new XElement("Departments",
new XElement("Department",
new XAttribute("id", 1),
new XElement("DeptName", "CS"))));
doc.Save(strPath);
}
Xml document must have only one root element. But you are trying to add both Departments and Employees nodes at root level. Add some root node to fix this:
doc = new XDocument(
new XElement("RootName",
new XElement("Employees",
new XElement("Employee",
new XAttribute("id", 1),
new XElement("EmpName", "XYZ"))),
new XElement("Departments",
new XElement("Department",
new XAttribute("id", 1),
new XElement("DeptName", "CS"))))
);
You need to add root element.
doc = new XDocument(new XElement("Document"));
doc.Root.Add(
new XElement("Employees",
new XElement("Employee",
new XAttribute("id", 1),
new XElement("EmpName", "XYZ")),
new XElement("Departments",
new XElement("Department",
new XAttribute("id", 1),
new XElement("DeptName", "CS")))));
In my case I was trying to add more than one XElement to xDocument which throw this exception. Please see below for my correct code which solved my issue
string distributorInfo = string.Empty;
XDocument distributors = new XDocument();
XElement rootElement = new XElement("Distributors");
XElement distributor = null;
XAttribute id = null;
distributor = new XElement("Distributor");
id = new XAttribute("Id", "12345678");
distributor.Add(id);
rootElement.Add(distributor);
distributor = new XElement("Distributor");
id = new XAttribute("Id", "22222222");
distributor.Add(id);
rootElement.Add(distributor);
distributors.Add(rootElement);
distributorInfo = distributors.ToString();
Please see below for what I get in distributorInfo
<Distributors>
<Distributor Id="12345678" />
<Distributor Id="22222222" />
</Distributors>

Categories