how to read all "Map" name and associate "Role" - c#

I have a config file like below,
<Hello>
<Maps>
<Map name="X1">
<Roles>
<Role name="Y1" />
</Roles>
</Map>
<Map name="X2">
<Roles>
<Role name="Y2" />
</Roles>
</Map>
</Maps>
</Hello>
Now I want to loop through all the "Map" (X1, X2), but below line of code giving me only one map X2, how to get both,
var a = ConfigurationManager.GetSection("Hello");

This link may help:
XML reading child nodes
You need to have a for-each loop as one of the answers in the link.

Related

Iterating through linq results results in more items than query count

I'm fairly new to LINQ but this seemed pretty straightforward.
I have an XML doc which contains a structure like this:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<folders>
<folder id="-1" parent="-100">
<name><![CDATA[Root]]></name>
<children>
<folder id="2" parent="-1">
<name><![CDATA[Contribution]]></name>
<documents />
<children>
<folder id="775" parent="2">
<name><![CDATA[category1]]></name>
<documents />
<children>
<folder id="2319" parent="775">
<name><![CDATA[Acad_Depts1]]></name>
<documents />
<children>
<folder id="26965" parent="2319">
<name><![CDATA[Student1]]></name>
<documents>
<document>
</document>
</documents>
</folder
</children>
</folder>
<folder id="2319" parent="775">
<name><![CDATA[Acad_Depts2]]></name>
<documents />
<children>
<folder id="26965" parent="2319">
<name><![CDATA[Student1]]></name>
<documents>
<document>
</document>
</documents>
</folder
</children>
</folder>
etc...
</children>
</folder>
</children>
</folder>
</children>
</folder>
</folders>
What I'm trying to do is to select all the elements with an attribute 'parent="775"'.
XElement xelement = XElement.Load("folders_only_registrar_folder.xml");
IEnumerable <XElement> folders = xelement.Elements();
var query = from node in folders.Descendants("folder")
where node.Attribute("parent").Value == registrarNodeID
select node;
Console.WriteLine(query.Count());
Console.ReadKey();
foreach(XElement departmentNode in query.Descendants("name"))
{
Console.WriteLine(departmentNode.Value.ToString());
}
When I run the query and test the count, I get 48 results (which is good)... but when I try to write out those same nodes, I get hundreds of results. For some reason it's giving me almost ALL of the elements named "folder" including children folders.
Thoughts as to what I'm doing wrong?
UPDATE... ok so now I know why i'm getting all the folders but any thoughts on how to create a collection of each grouping of nodes and sub-nodes?
Can the selection in LINQ send each 775 folder node (plus it's collective sub-nodes) into some sort of collection of nodes and then I could parse through them in a foreach by grouping of node?
Replace query.Descendants() with just query. query.Descendants() gets every child of every node that was originally contained within query.

How to insert an XML File into Another XML File at Specific Node C#

I have two XML Files ,the first one is and Named as XMLTemplate
<DataSources>
<DataSource Name="XXXX">
</DataSource>
<DataSource Name="ABC">
</DataSource>
</DataSources>
<DataSets>
<DataSet Name="abc">
<Query>
</Query>
<ReportSections>
</ReportSections>
and the second xml file is named as XMLGenrated,
<Fields>
<Field >
</Field>
</Fields>
and I need the Output as,
<DataSource Name="XXXX">
</DataSource>
<DataSource Name="ABC">
</DataSource>
</DataSources>
<DataSets>
<DataSet Name="abc">
<Query>
<Fields>
<Field >
</Field>
</Fields>
</Query>
<ReportSections>
</ReportSections>
Both the Files are in .XML Extension and I dont know how to find the node by its Name Can anyone help me out.
I tried this,
XElement xFileRoot = XElement.Load(XMLTemplate.xml);
XElement xFileChild = XElement.Load(XMLGenerated.xml);
xFileRoot.Add(xFileChild);
xFileRoot.Save(file1.xml);
but the XML adds below the XMLTemplate I dont know how to insert at particular node.
Find the node using Linq to XML and Replace its contents
XElement xFileRoot = XElement.Load(XMLTemplate.xml);
XElement xFileChild = XElement.Load(XMLGenerated.xml);
var queryNode = xFileRoot.Element("Query");
queryNode.ReplaceWith(xFileChild) ;
Based on on this answer - How can I update/replace an element of an XElement from a string?
Be aware that you sample XML files contain multiple root nodes, and that if you need to keep the <Query> node you need to change this.

XML Traffic Copping

I have an "xml-source" that is sending me XML.
The xml can come in two ways. One that is "Order" related. A second that is "Employee" related.
Typically, when I shred xml, I use some Linq-To-Xml to parse a known xml-schema.
But now, with 2 different xml-schema's coming at me, I am trying to find the most efficient way to "traffic cop" the Xml.
What I've tried is:
Parse "version1".........and then check for mandatory (order) data (like valid OrderId's). If that data isn't there, then:
Parse for "version2"........then check for mandatory employee data, like employeeSSN.
If both fail, then I log that I didn't get either.
Any ideas on what is the most efficient way to do this traffic copping of the Xml?
My other idea is the create xsd's, and validate. But then I'm running a xsd-validate....and then sending it to a "parser".....so that may be less efficient than the idea above...of try1, try2, then fail.
While I can choose when I traffic-cop the xml, I cannot change the way the xml is sent to me. The xml is put on a queue, and the architecture does not allow for putting different xml's on different queues.....via contract with the third party vendor.
Any idea that I'm not seeing?
I don't like different xml's on the same queue............but that's ship has sailed.
The xml's below are made up........but show that the xml's are just completely different and share nothing.
<root>
<orders>
<order orderId="ABC123">
<orderDetails>
<orderDetail itemName="Bike" quantity="1"/>
<orderDetail itemName="TeddyBear" quantity="2"/>
<orderDetail itemName="Doll" quantity="3"/>
</orderDetails>
</order>
<!-- -->
<order orderId="DEF234">
<orderDetails>
<orderDetail itemName="Truck" quantity="4"/>
<orderDetail itemName="Marbles" quantity="5"/>
<orderDetail itemName="BoardGame" quantity="6"/>
</orderDetails>
</order>
</orders>
</root>
<root>
<employees>
<employee employeeSSN="222222222" firstName="John">
<employeeEmails>
<employeeEmail emailValue="john#home.com" />
<employeeEmail emailValue="john#work.com" />
</employeeEmails>
</employee>
<!-- -->
<employee employeeSSN="3333333" firstName="Mary">
<employeeEmails>
<employeeEmail emailValue="mary#home.com" />
<employeeEmail emailValue="mary#work.com" />
<employeeEmail emailValue="mary#spamcatcher.com" />
</employeeEmails>
</employee>
</employees>
</root>

Creating Maintainable Xml structure for a relational database

I am not trying to save dataset or datatable to a xml file rather create a xml structure for saving related data? For example i would like to know how below data could be in a xml file
User
UserId
Username
Password
Roles
RoleId
UserId [FK]
CreatedOn
will it look like this
<User userid="" username="" password="">
<Roles id="">
<Name></Name>
<Description></Description>
</Roles>
</User>
which structure would be best to use xml files as DB
I think you want to consider implementing the XML in a more normalized manner, similar to how you would do so with a relational database. For instance in your current solution you would be required to type out the entire role structure within every user such as
<User userid="1" username="user01" password="password">
<Roles id="1">
<Name>Role 1</Name>
<Description>This is Role 1</Description>
</Roles>
</User>
<User userid="2" username="user02" password="password">
<Roles id="1">
<Name>Role 1</Name>
<Description>This is Role 1</Description>
</Roles>
</User>
A normalized structure could look like the following
<Roles>
<Role id="1">
<Name>Role 1</Name>
<Description>This is Role 1</Description>
</Role>
</Roles>
<User id="1" username="user01" password="password">
<Roles>
<Role>1</Role>
</Roles>
</User>
<User id="2" username="user02" password="password">
<Roles>
<Role>1</Role>
</Roles>
</User>
Hope this helps

creating a "join" to update one XElement from another XElement

I have an XElement, called "XUsers", that will contain XML which looks like this:
<users>
<user id="12345" name="Bob Smith" />
<user id="67890" name="Jamal Stevens" />
<user id="54321" name="Mary Jones" />
</users>
...and another XElement, called "XTasks", that will contain data like this:
<tasks>
<task id="1" title="Task 1" ownerId="54321" />
<task id="2" title="Task 2" ownerId="12345" />
<task id="3" title="Task 3" ownerId="67890" />
</tasks>
I want to add an attribute ("ownerName") to the task elements in the second XElement (XTasks), and set its values according to a "join" with the first XElement (XUsers). So, my final result will be that the XML in XTask will look like this:
<tasks>
<task id="1" title="Task 1" ownerId="54321" ownerName="Mary Jones" />
<task id="2" title="Task 2" ownerId="12345" ownerName="Bob Smith" />
<task id="3" title="Task 3" ownerId="67890" ownerName="Jamal Stevens" />
</tasks>
Is this possible using Linq? I haven't been able to find any examples of this sort of operation on the web. What is the most efficient way to accomplish this in my ASP.NET(C#) code?
Thanks for any advice you can give.
I am doing this without any IDE in front of me, so forgive me for any errors..
foreach (XElement task in XTasks.Elements())
{
XElement userNode = XUsers.Elements().Where(
e => e.Attribute("id").Value == task.Attribute("ownerId").Value).FirstOrDefault();
if (userNode != null)
{
task.Attribute("ownerName").SetValue(userNode.name);
}
}

Categories

Resources