Solved

What's the most concise method to validate this xml report?

Posted on 2011-03-22
8
251 Views
Last Modified: 2012-05-11
I have the attached xml "message" that contains a report I need to validate against the data contained in the server database. I have been working on it for a while and I am using a few foreach loops to handle the levels.

I'm fine with the way I am actually validating the data itself, but...

I think there has to be a better way to iterate through the xml nodes to validate the data.

What is the most concise method to interate throug the xml when it has varying levels like the attached xml?
<Message message_type="data_validation" store_id="206" register_id="1">
  <Reports>
    <Report name="TSR" generated="03/20/2011 14:00:53" fromDate="03/19/2011" throughDate="03/19/2011" reportingRegisters="1" remote_synch_key="519181">
      <Section name="Section1">
        <Field name="Field1" value="$600.79" />
        <Field name="Field2" value="$600.79" />
      </Section>
      <Section name="Section 2">
        <Field name="Field3" value="$0.00" />
      </Section>
      <Section name="Section3">
        <Subsection name="Section4">
          <Field name="Field5" qty="3" value="($18.64)" />
          <Field name="Field6" qty="3" value="($18.64)" />
        </Subsection>
        <Subsection name="Section4">
          <Field name="field2" qty="5" value="($26.55)" />
          <Field name="field7" qty="4" value="($3.46)" />
        </Subsection>
        <Field name="field3" qty="12" value="($48.65)" />
        <Field name="field8" value="8.82" />
      </Section>
    </Report>
  </Reports>
</Message>

Open in new window

0
Comment
Question by:dgerler
  • 4
  • 3
8 Comments
 
LVL 75

Expert Comment

by:käµfm³d 👽
ID: 35193248
Is there a schema or DTD for this XML? There are several classes in .NET you can use to validate XML against a schema or DTD.
0
 
LVL 7

Expert Comment

by:dimaj
ID: 35194609
Take a look at Linq with XML. You can easily find any node you want and then validate them against your database.

The general idea is as follows:
XDocument doc = XDocument.Load("your xml stuff");

List<XElement> errors =
from report in doc.Root.DescendantsAndSelf("Report")
from section in report.DescendantsAndSelf("Section")
from subsection in section.DescendantsAndSelf("Subsection")
from field in subsection.DescendantsAndSelf("Field")
where DataIsInvalid(field)
select field).ToList();

Please note, that DataIsInvalid is a function that you must define which will test whether or not your data validates against your database.
At the end of this command, your 'errors' variable will contain all nodes that could not be validated.

Hope this will get you started.
0
 
LVL 7

Accepted Solution

by:
dimaj earned 500 total points
ID: 35194684
A little correction:

Here's how your code should look:
public void SomeFunc (string str) {
  // please note that Load takes a Stream object or a file location
  XDocument doc = XDocument.Load(str);
  List<XElement> nodes = (from n in doc.Root.DescendantsAndSelf("Field")
                          select n).ToList();
}

Open in new window


Then, when you loop through your list of nodes, use 'Parent' property to identify the location where this node is in the tree. You can also test that before selecting the node. In this case your code would look like this:
 
public void SomeFunc (string str) {
  // please note that Load takes a Stream object or a file location
  XDocument doc = XDocument.Load(str);
  List<XElement> nodes = (from n in doc.Root.DescendantsAndSelf("Field")
                          where MyCriteriaIsNotMet(n)
                          select n).ToList();
}

private bool MyCriteriaIsNotMet(XElement node) {
  // do your node tests here
}

Open in new window

0
3 Use Cases for Connected Systems

Our Dev teams are like yours. They’re continually cranking out code for new features/bugs fixes, testing, deploying, testing some more, responding to production monitoring events and more. It’s complex. So, we thought you’d like to see what’s working for us.

 

Author Comment

by:dgerler
ID: 35199380
DescendentsAndSelf does not take any arguements. When left out, I get every node, not just field nodes.
0
 

Author Comment

by:dgerler
ID: 35199391
By the way, I should be more clear. The "validation" is more a compare of he values to determine if they match.
0
 
LVL 7

Expert Comment

by:dimaj
ID: 35199622
DescendantsAndSelf should have an optional argument of node name.
As far as validation goes, your ' where' clause could be a function that takes current node and an expected value, then compare the two and return true or false.
0
 

Author Comment

by:dgerler
ID: 35199660
OK.. What I really wanted was:

List<XElement> nodes = (from n in doc.Root.Descendants("Field")  select n).ToList();

Which gives me a List of the Field nodes.

then I am using

string currentField = node.Parent.Attribute("name").Value + " - " + node.Attribute("name").Value;

to get my identifier for the particular field to compare.
0
 
LVL 7

Expert Comment

by:dimaj
ID: 35199715
Ok, so that gives you either section out subsection... What is your "validation rule"?
0

Featured Post

DevOps Toolchain Recommendations

Read this Gartner Research Note and discover how your IT organization can automate and optimize DevOps processes using a toolchain architecture.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Entity Framework is a powerful tool to help you interact with the DataBase but still doesn't help much when we have a Stored Procedure that returns more than one resultset. The solution takes some of out-of-the-box thinking; read on!
Calculating holidays and working days is a function that is often needed yet it is not one found within the Framework. This article presents one approach to building a working-day calculator for use in .NET.
Two types of users will appreciate AOMEI Backupper Pro: 1 - Those with PCIe drives (and haven't found cloning software that works on them). 2 - Those who want a fast clone of their boot drive (no re-boots needed) and it can clone your drive wh…
The Email Laundry PDF encryption service allows companies to send confidential encrypted  emails to anybody. The PDF document can also contain attachments that are embedded in the encrypted PDF. The password is randomly generated by The Email Laundr…

770 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question