Write xmlelement using LINQ C# - c#

How the below content can be convert to xml using LINQ
List<int> calllist = new List<int>();
calllist.Add(10);
calllist.Add(5);
calllist.Add(1);
calllist.Add(20);
The output should be:
<root>
<child>
<name>1</name>
<count>1</count>
</child>
<child>
<name>5</name>
<count>1</count>
</child>
<child>
<name>10</name>
<count>1</count>
</child>
<child>
<name>20</name>
<count>1</count>
</child>
</root>
I tried something like:
XElement root = new XElement ("root",
new XElement("child",new XElement(from c in calllist select c; /*error here*/ )));
But got stuck up and unable to proceed. Can anyone share a solution to make this work?

#user833985
Try the below.
XElement root = new XElement(
"root", from c in calllist orderby c select
new XElement("child",
new XElement("name", c),
new XElement("count",calllist.Count))
);

XElement root =
new XElement("root",
calllist
.GroupBy(c => c)
.OrderBy(g => g.Key)
.Select(g => new XElement("child",
new XElement("name", g.Key),
new XElement("count",g.Count())
)
)
);

Related

convert list to xml in c#

I have a list of string. I need to convert it into an xml document. Am using XElement to achieve this.
List<string> list= myString.Split(',').ToList();
XElement xmlElements = new XElement("Root", new XElement("Number",list.Select(i => new XElement("Num", i))));
System.Console.Write(xmlElements);
System.Console.Read();
I get the below format.
<Root>
<Number>
<Num></Num>
<Num></Num>
</Number>
</Root>
But I need something like this.
<Root>
<Number id=1>
<Num></Num>
</Number>
<Number id=2>
<Num></Num>
</Number>
</Root>
How to achieve this.
If by an id you mean an index, then:
XElement xmlElements =
new XElement("Root",
list.Select((i, index) => new XElement("Number",
new XAttribute("id", index),
new XElement("Num", i))));
The result for the "a,b,c" will be
<Root>
<Number id="0">
<Num>a</Num>
</Number>
<Number id="1">
<Num>b</Num>
</Number>
<Number id="2">
<Num>c</Num>
</Number>
</Root>

Adding elements to XDocument at runtime from DataTable

I am trying to generate an XML using XDocument by pulling data from a DataTable at runtime. I want to have the output in this format:
<Document>
<Alphabets>
<Data>
<Capital>AAA</Capital>
<Small>aaa</Small>
</Data>
</Alphabets>
<Language>
<Name>English</Name>
</Language>
<Alphabets>
<Data>
<Capital>BBB</Capital>
<Small>bbb</Small>
</Data>
</Alphabets>
<Language>
<Name>English</Name>
</Language>
</Document>
The Language element has to be present after every Alphabets element. I have tried very hard to achieve this but I am unable to put this Alphabets tag after every Language element. What I have achieved is this, where the Language element is falling inside Alphabets element:
<Document>
<Alphabets>
<Data>
<Capital>AAA</Capital>
<Small>aaa</Small>
</Data>
<Language>
<Name>English</Name>
</Language>
</Alphabets>
<Alphabets>
<Data>
<Capital>BBB</Capital>
<Small>bbb</Small>
</Data>
<Language>
<Name>English</Name>
</Language>
</Alphabets>
</Document>
Here is my code :
static void Main(string[] args)
{
DataTable dtAlpha = new DataTable("Alphabetss");
dtAlpha.Columns.Add("Capital", typeof(string));
dtAlpha.Columns.Add("Small", typeof(string));
dtAlpha.Rows.Add("AAA", "aaa");
dtAlpha.Rows.Add("BBB", "bbb");
XDocument doc = new XDocument(
new XDeclaration("1.0", "UTF-8", null),
new XElement("Document",
from row in dtAlpha.AsEnumerable()
select new XElement("Alphabets",
new XElement("Data",
new XElement("Capital", row.Field<string>("Capital")),
new XElement("Small", row.Field<string>("Small"))
),
new XElement("Language",
new XElement("Name", "English")
)))
);
Console.WriteLine(doc.ToString());
Console.ReadKey();
}
Please help me on this.
You can try this way :
XDocument doc = new XDocument(
new XDeclaration("1.0", "UTF-8", null),
new XElement("Document")
);
foreach(var row in dtAlpha.AsEnumerable())
{
var alphabets = new XElement("Alphabets",
new XElement("Data",
new XElement("Capital", row.Field<string>("Capital")),
new XElement("Small", row.Field<string>("Small"))
)
);
var language = new XElement("Language",
new XElement("Name", "English")
);
doc.Root.Add(alphabets);
doc.Root.Add(language);
}

Linq to XDocument Group by subset

I am looking for a linq to Xdoc query to group by a subset of the XML nodes. I've only been able to get this working to return a subset of the data but I need the entire xml document passed back with only the particular nodes grouped.
<Root>
<Elementname1>
</Elementname1>
<Elementname2>
</Elementname2>
<Elementname3 attrname="test1">
<Child>
</Child>
</Elementname3>
<Elementname3 attrname="test1">
<Child>
</Child>
</Elementname3>
</Root>
This code:
var result =
from row in xDoc.Descendants("Elementname3")
group row by (string)row.Attribute("attrname") into g
select g.First();
returns:
<Elementname3 attrname="test1">
<Child></Child>
</Elementname3>
Expecting:
<Root>
<Elementname1>
</Elementname1>
<Elementname2>
</Elementname2>
<Elementname3 attrname="test1">
<Child>
</Child>
</Elementname3>
</Root>
I understand since descendant element is starting at elementname3; just not sure on how to expound the linq query to start with the root node and group as expected.
Try this:
var result = new XDocument(
new XElement("Root",
from x in doc.Root.Elements()
group x by new { x.Name, Attr = (string)x.Attribute("attrname") } into g
select g.First()
)
);

How to return XML node inner text comparing it to same descendant?

I have a xml file like this:
<Tests>
<Test>
<Name>Test1</Name>
<Type>A</Type>
</Test>
<Test>
<Name>Test2</Name>
<Type>A</Type>
</Test>
<Test>
<Name>Test3</Name>
<Type>B</Type>
</Test>
</Tests>
How can I return a string array or list which only contains name of the Test which theire type is A?
I am trying with this code but no success!
XPathNodeIterator it = nav.Select("/Tests/Test[Type = 'A']/Name)
Don't you want to try linq2xml?
using System.Xml.Linq;
using System.Linq;
///////////
XElement root = new XElement("Tests",
new XElement("Test",
new XElement("Name", "Test1"),
new XElement("Type", "A")),
new XElement("Test",
new XElement("Name", "Test2"),
new XElement("Type", "A")),
new XElement("Test",
new XElement("Name", "Test3"),
new XElement("Type", "B")));
string[] result = (from xe in root.Elements()
where xe.Element("Type").Value.Equals("A")
select xe.Element("Name").Value).ToArray();
The XPath expression in your question matches Name elements. If you want to match Test elements instead, you have to remove the /Name part:
XPathNodeIterator it = nav.Select("/Tests/Test[Type = 'A']);
If you want to use an XPathNavigator, from there, you can call MoveToChild() to point the navigator to the Name elements:
foreach (XPathNavigator elemNav in it) {
elemNav.MoveToChild("Name", "");
string name = elemNav.Value;
// Do something with 'name'...
}

How can I sort an XDocument by attribute?

I have some XML
<Users>
<User Name="Z"/>
<User Name="D"/>
<User Name="A"/>
</User>
I want to sort that by Name. I load that xml using XDocument. How can I view that xml sorted by Name?
You can sort using LINQ to Xml, if XmlDocument is not the case
XDocument input = XDocument.Load(#"input.xml");
XDocument output = new XDocument(
new XElement("Users",
from node in input.Root.Elements()
orderby node.Attribute("Name").Value descending
select node));
XDocument xdoc = new XDocument(
new XElement("Users",
new XElement("Name", "Z"),
new XElement("Name", "D"),
new XElement("Name", "A")));
var doc = xdoc.Element("Users").Elements("Name").OrderBy(n => n.Value);
XDocument doc2 = new XDocument(new XElement("Users", doc));

Categories

Resources