如果净XML Schema验证停止在到达第一个无效的元素? [英] Should .Net XML Schema Validation stop upon reaching first invalid element?

查看:114
本文介绍了如果净XML Schema验证停止在到达第一个无效的元素?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个XML字符串,并装起来,并传递给函数的模式。我有它验证对正确模式的XML,但它总是停在第一个无效元素的范围验证。无效的数据,它保持下去,无效/缺少的属性,不断去,但无效元素,它停止,不会再在该范围内验证。

I have an XML string and a Schema loaded up and passed into a function. I have it validating the XML against the schema correctly, however it always stops validating at the scope of the first invalid element. Invalid data, it keeps going, invalid/missing attributes, keeps going, but invalid elements, it stops and will not validate further within that scope.

的模式如下:

<?xml version="1.0" encoding="utf-16"?>
<xs:schema xmlns:b="http://schemas.microsoft.com/BizTalk/2003" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="root">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="items">
          <xs:complexType>
            <xs:sequence maxOccurs="unbounded">
              <xs:element name="foo">
                <xs:complexType>
                  <xs:sequence>
                    <xs:element name="bar" type="xs:integer" />
                    <xs:element name="bat" type="xs:integer" />
                  </xs:sequence>
                  <xs:attribute name="attr1" type="xs:integer" use="required" />
                </xs:complexType>
              </xs:element>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

XML如下:

<root>
  <items>
    <foo attr1='1'>
      <invalid0>1</invalid0>
      <invalid1>b</invalid1>
    </foo>
    <foo attr1='1'>
      <invalid2>b</invalid2>
      <bat>b</bat>
    </foo>
    <foo attr1='1'>
      <bar>3</bar>
    </foo>
    <invalidFoo attr1='1'>
      <bar>d</bar>
      <bat>2</bat>
    </invalidFoo>
    <foo>
      <bar>3</bar>
      <bat>q</bat>
    </foo>
  </items>
</root>

在这个例子中,验证到达第一个

那么,会发生什么&LT;富&GT; ,看到&LT; invalid0&GT; &LT内不验证;富&GT; 任何进一步的,因此错过了&LT; invalid1&GT; 。验证移动到下一个&LT;富&GT;

So, what happens in this example the validator reaches the first <foo> and sees <invalid0> and doesn't validate within the <foo> any further and therefore misses the <invalid1>. Validator moves on to the next <foo>.

接下来&LT;富&GT; 它看到有一个&LT; invalid2&GT; 不属于那里而且不打扰赶上无效数据的&LT;球棒GT; 元素(字符串而不是整数)。这将直接进入下一个&LT;富&GT;

The next <foo> it sees there is an <invalid2> which doesn't belong there and doesn't bother to catch the invalid data for the <bat> element (string instead of integer). It goes directly to the next <foo>

这使得它到下一个&LT;富&GT; 元素,并引发有关错误缺少&LT;球棒GT; 并移动到下一个&LT;富&GT; ,酷

It makes it to the next <foo> element and throws an error about a missing <bat> and moves on to the next <foo>, cool.

现在它到达了&LT; invalidFoo&GT; 是理所当然的,简化版,做任何验证&LT内; invalidFoo&GT; 当然,因为,什么是&LT; invalidFoo&GT;

Now it gets to the the <invalidFoo> and rightfully so, does't do any validation inside of the <invalidFoo> because, of course, what's an <invalidFoo>?

的关键点对我来说是,在这一点上验证停止验证以下所有&LT;富&GT; 兄弟元素,所以无效在过去的数据&LT;球棒GT; 没有被捕获。所以,现在,我问的原因是因为我使用的验证方法是尝试捕捉所有的错误(或者至少是尽可能多),并将它们传回给用户。第一个测试我在实际code确实是这样相当于:

The sticking point for me is, at this point the validator stops validating all the following <foo> sibling elements, so the invalid data in the last <bat> is not caught. So now, the reason I'm asking is because the way I'm using validation is to try to catch all errors (or at least as many as possible) and pass them back to the user. The first test I did in my actual code was the equivalent of this:

<root>
  <items>
    <invalidFoo attr1='1'>
      <invalid0>1</invalid0>
      <invalid1>b</invalid1>
    </invalidFoo>
    <foo attr1='1'>
      <invalid2>b</invalid2>
      <bat>b</bat>
    </foo>
    <foo attr1='1'>
      <bar>3</bar>
    </foo>
    <invalidFoo attr1='1'>
      <bar>d</bar>
      <bat>2</bat>
    </invalidFoo>
    <foo>
      <bar>3</bar>
      <bat>q</bat>
    </foo>
  </items>
</root>

所以,验证看到第一个&LT; invalidFoo&GT; 和拦死了。在很长的时间,我是假设,由于某种原因验证总是停在第一个错误。直到我添加了一个有效的&LT;富&GT; 返回其开始抓,并陆续积累了其他无效数据错误。但是当它击中一个无效的元素标记名,所有的兄弟姐妹/子级验证被跳过。它只发生在无效元素,没有属性或数据。

So, the validator saw that first <invalidFoo> and stopped dead. For the longest time, I was assuming that for some reason the validation was always stopping on the first error. It wasn't until I added a valid <foo> back that it started catching and accumulating the other invalid data errors in succession. But as soon as it hits an invalid element tagname, all sibling/child-level validation is skipped. It only happens upon invalid elements, not attributes or data.

现在,我并不是说这是对还是错?我问,如果这是对还是错? 如果验证继续下去,特别是在兄弟元素的情况下?还是应停止和基本要求无效的基础上previous之一是无效元素的完整列表?什么是Xml架构验证在这种情况下,预期的行为?

Now, I'm not saying this is right or wrong...I'm asking if this is right or wrong? Should the validator keep going, especially in the case of sibling elements? Or should it be stopping and basically calling an entire list of elements invalid based on a previous one being invalid? What is the expected behaviour of the Xml Schema Validator in this situation?

这是所有正在使用下面的C#code(其中工程,我希望它)来实现:

This is all being done using the following C# code (which works as I expect it to):

 public static void ValidateAgainstSchema(string XMLSourceDocument, XmlSchemaSet validatingSchemas)
 {
    if (validatingSchemas == null)
    {
        throw new ArgumentNullException("In ValidateAgainstSchema: No schema loaded.");
    }

    string errorHolder = string.Empty;
    ValidationHandler handler = new ValidationHandler();

    XmlReaderSettings settings = new XmlReaderSettings();
    settings.CloseInput = true;
    settings.ValidationType = ValidationType.Schema;
    settings.ValidationEventHandler += new ValidationEventHandler(handler.HandleValidationError);
    settings.Schemas.Add(validatingSchemas);
    settings.ValidationFlags =
        XmlSchemaValidationFlags.ReportValidationWarnings |
        XmlSchemaValidationFlags.ProcessIdentityConstraints |
        XmlSchemaValidationFlags.ProcessInlineSchema |
        XmlSchemaValidationFlags.ProcessSchemaLocation;

    StringReader srStringReader = new StringReader(XMLSourceDocument);

    using (XmlReader validatingReader = XmlReader.Create(srStringReader, settings))
    {
        while (validatingReader.Read()) { }
    }

    if (handler.MyValidationErrors.Count > 0)
    {
        foreach (String messageItem in handler.MyValidationErrors)
        {
            errorHolder += messageItem;
        }
        throw new XmlSchemaValidationException(errorHolder);
    }
}

验证事件处理程序刚刚捕获的错误,并将它们添加到的IList&LT;字符串&GT; 显示后一起

推荐答案

它确实步行一棵树,所以一旦它得到了不适合的节点元素,它的丢失。 但属性不分层,他们是一个列表,所以这是一个直合格/不合格,它可以继续,类型检查也很简单。

It does elements by walking a tree, so as soon as it gets a node that doesn't fit, it's lost. Attributes however are not hierarchical, they are a list, so it's a straight go / no go, and it can continue, type checking is simple as well.

您可以看看你的榜样,想好了就可以处理的怎么样这虽然。

You can look at your example and think well it could deal with that what about this though.

<root>
  <items>
    <invalidFoo attr1='1'>
      <invalid0>1</invalid0>
      <invalid1>b</invalid1>
      <foo attr1='1'>
        <bar>b</bar>
        <bat>b</bat>
      </foo>    
    </invalidFoo>
  <items>
<root>

如果FOO被视为项目或不是一个孩子。 FOO是真的富?

Should foo be treated as a child of items or not. Is foo really a foo?

如果你想有一个真正的头弯管机想象有一个的xsd:选择或两个在那里,有一个选择不符合该模式有效节点。 它的那些情况下,它是危险的,试图继续之一,所以它提示出来,说,你需要解决这个问题第一,所以我可以理智地验证什么来后。

If you want a real head bender imagine having an xsd:choice or two in there and having a selection of valid nodes that don't meet the schema. It's one of those situations, where it's "dangerous" to try and continue, so it tips out and says you need to fix this first so I can sensibly validate what comes after.

这篇关于如果净XML Schema验证停止在到达第一个无效的元素?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆