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?

[Webinar] Streamline your web hosting managementRegister Today

x
 
nmarunConnect With a Mentor Commented:
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
 
nmarunConnect With a Mentor Commented:
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
 
nmarunConnect With a Mentor Commented:
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
Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

 
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
All Courses

From novice to tech pro — start learning today.