Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 261
  • Last Modified:

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

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
dgerler
Asked:
dgerler
  • 4
  • 3
1 Solution
 
käµfm³d 👽Commented:
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
 
dimajCommented:
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
 
dimajCommented:
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
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
dgerlerAuthor Commented:
DescendentsAndSelf does not take any arguements. When left out, I get every node, not just field nodes.
0
 
dgerlerAuthor Commented:
By the way, I should be more clear. The "validation" is more a compare of he values to determine if they match.
0
 
dimajCommented:
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
 
dgerlerAuthor Commented:
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
 
dimajCommented:
Ok, so that gives you either section out subsection... What is your "validation rule"?
0

Featured Post

How to Use the Help Bell

Need to boost the visibility of your question for solutions? Use the Experts Exchange Help Bell to confirm priority levels and contact subject-matter experts for question attention.  Check out this how-to article for more information.

  • 4
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now