LINQ to XML in a WCF Service

Hello Experts,
    I have to create a wcf service and inside the service i have to do some basic operations on a xml file using LINQ to XML. I have to host the service in IIS 7.0 and consume it.
As part of the LINQ to XML I have to do the following tasks :
1. find all the questions in all the tests that answers are no
2. modify the question and answer of Test id="test2"
3. save the xml to db and then extract values such as question and answers
4. save the test and questions into a normalized db with tables such as Test and Question based on given xml

Pasted below is the XML file.
<b:ServiceInstanceSet
xmlns:b="b:urn:schemas-microsoft-com:billing-data">
<b:MigrationStatus>
1</ b:MigrationStatus>
<b:ServiceInstance>
<b:ServiceInstanceId>
KwEAAAAAAAABAAEA</ b:ServiceInstanceId>
</b:ServiceInstance>
<b:Tests>
<b:Test id="test1">
<b:Question id="1" question="is the sky blue?" answer="yes"/>
<b:Question id="3" question="is this hard exercise?" answer="no"/>
<b:Question id="2" question="is the grass green?" answer="yes"/>
</b:Test>
<b:Test id="test2">
<b:Question id="1" question="what is cni?" answer="insurance company"/>
<b:Question id="2" question="is this hard exercise?" answer="no"/>
</b:Test>
</b:Tests>
</b:ServiceInstanceSet>
maadhukariAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

nmarunCommented:
The first thing I'd do is to get this structure in a class. I have the following code work for me.

Arun

private static void NestedXml()
{
    XDocument doc = XDocument.Load(xmlFilePath);
    XNamespace xmlns = "b:urn:schemas-microsoft-com:billing-data";

    List<Test> tests = (from test in doc.Descendants(xmlns + "Test")
                        select new Test
                                    {
                                        Id = test.Attribute("id").Value,
                                        Questions = (from question in test.Descendants(xmlns + "Question")
                                                    select new Question()
                                                                {
                                                                    Id =
                                                                        int.Parse(question.Attribute("id").Value),
                                                                    Question1 =
                                                                        question.Attribute("question").Value,
                                                                    Answer = question.Attribute("answer").Value,
                                                                }).ToList()
                                    }).ToList();
}

public class Test
{
    public string Id { get; set; }
    public List<Question> Questions { get; set; }
}

public class Question
{
    public int Id { get; set; }
    public string Question1 { get; set; }
    public string Answer { get; set; }
}

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
nmarunCommented:
Once you get your xml mapped to a class as done above, you can start writing LINQ on the 'tests' instance itself. The below will get you the solution for your first concern.

List<Question> questionsAnsweredNo = (from test in tests
                                        from question in test.Questions
                                        where question.Answer.ToLower() == "no"
                                        select question).ToList();

Arun
0
nmarunCommented:
You can have a method on the Test class called 'SaveTest()'. This would save the individual test to your database in a normalized format and a similar method on the Question class to save the questions and answers to the database table.

Arun
0
Cloud Class® Course: CompTIA Healthcare IT Tech

This course will help prep you to earn the CompTIA Healthcare IT Technician certification showing that you have the knowledge and skills needed to succeed in installing, managing, and troubleshooting IT systems in medical and clinical settings.

maadhukariAuthor Commented:
Thank you very much Arun.
     Another part of the question is I want this to be exposed as a WCF service.
Thanks
Maadhukari
0
maadhukariAuthor Commented:
Hi Arun,
  I am sorry. I am new to programming. How can i associate NestedXml()  with test or Question Classes.
0
nmarunCommented:
What exactly do you want to be exposed as a service? Each of the tasks you've mentioned above?

So I'm assuming the input for your service method is the xml posted above. If that's the case, here's how I would go about building that.

I would keep the NestedXml() method as a private method that returns List<Test> based on the xml input. I would change its name though to something appropriate.

I'll have a service method called 'ParseTests' that takes in the xml as a parameter. Here's the pseudocode:

public void ParseTests(string xmlInput)
{
    List<Test> tests = NestedXml(xmlInput);
    // this is for the second requirement
    // I'm not sure what you want in this method
    // so you can create/use it appropriately
    ModifyTestValues(ref tests);
    // Persist the tests to a database
    SaveTests(tests);
}

private void SaveTests(List<Test> tests)
{
    for(int i = 0; i<tests.Count; i++)
    {
       // as mentioned above, create a method called SaveTest()
       // in the Test class that takes care of saving the test details
       // and the List<Question> property to the database
       tests[i].SaveTest();
    }
}

You can have a SaveQuestion() method on your Question class as well that will save the details of a Question type to the database, similar to the SaveTest() method.

If you need to learn about WCF here are some links:
http://msdn.microsoft.com/en-us/library/ms734712.aspx
http://www.wcftutorial.net/

Arun
0
nmarunCommented:
This does not make sense. I did give solution to read your XML and provided direction as to how to meet your requirements. 'Solved my problem' is not a good enough explanation for closing this without assigning points.

Arun
0
maadhukariAuthor Commented:
I am sorry, this is the first time I posted my question in this site. I am not familiar with the process. I did assign the points but i don't know what went wrong. I am going to assign the points.
0
maadhukariAuthor Commented:
Arun,
    Could you please provide the Linq to XML query to Modify.

ModifyTestValues(ref tests);

 modify the question and answer of Test id="test2" . Change the question to "How Big is CNI" and answer to "Multi Million Dollar Company"

Thanks
Maadhukari.
0
nmarunCommented:
LINQ stands for LANGUAGE INTEGRATED QUERY. Think of it as a 'select' statement that you run on your database table. This statement does not modify the table values right? So LINQ is not to be used for modifying your collection... only for querying.

You're better off using a for loop on the 'tests' instance and change it where required.

Arun
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
.NET Programming

From novice to tech pro — start learning today.