Проблема проверки XSD - PullRequest
3 голосов
/ 31 мая 2009

У меня есть следующее (ошибочное) Xml:

<jobs>
    <job>
        <id>1</id>
        <state><![CDATA[IL]]></state>
    </job>
    <job>
        <id>2</id>
    </job>
</jobs>

ИД, и узел состояния являются необходимыми элементами. Я написал для него Xsd:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="importvalidator"
    elementFormDefault="qualified"
    targetNamespace="http://foo.org/importvalidator.xsd"
    xmlns="http://foo.org/importvalidator.xsd"
    xmlns:mstns="http://foo.org/importvalidator.xsd"
    xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="jobs">
        <xs:complexType>
          <xs:sequence>
            <xs:element name="job" minOccurs="1" maxOccurs="unbounded">
              <xs:complexType>
                <xs:all>
                  <xs:element name="id" type="xs:string" minOccurs="1"/>
                  <xs:element name="state" type="xs:string" minOccurs="1"/>
                </xs:all>
              </xs:complexType>
            </xs:element>
          </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

И это все еще подтверждается как структурно допустимый Xml. Что мне здесь не хватает?

Update1: код, который я использую, находится на C #:

        XmlSchemaSet schemas = new XmlSchemaSet();
        schemas.Add("http://foo.org/importvalidator.xsd", "validator.xsd");

        XDocument doc = XDocument.Load(fileName);
        if (doc == null | doc.Root == null)
        {
            throw new ApplicationException("xml error: the referenced stream is not xml.");
        }

        doc.Validate(schemas, (o, e) =>
        {
            throw new ApplicationException("xsd validation error: xml file has structural problems");
        });

Ответы [ 3 ]

3 голосов
/ 31 мая 2009

Пожалуйста, отформатируйте ваш xml, чтобы его было легче читать, например:

<jobs>
  <job>
    <id>1</id>
    <state><![CDATA[IL]]></state>
  </job>
  <job>
    <id>2</id>
  </job>
</jobs>

Я думаю, что вы на самом деле не проверяете это - пространства имен означают, что этот XML не проверяет, даже с "<state>" во втором "<job>". В частности, XSD имеет целевое пространство имен "http://foo.org/importvalidator.xsd", но XML не имеет заданного пространства имен.

Настройте тривиальный тестовый пример XSD и XML, который, как вы точно знаете, потерпит неудачу - используйте его, чтобы отследить, почему вы не проверяете.

Кроме того, в вашем XSD отсутствуют закрывающие теги для элемента и схемы, поэтому он должен выдавать ошибку - или это просто неправильная вставка: -)


Вы можете удалить targetNamespace из схемы:

<xs:schema id="importvalidator"
    elementFormDefault="qualified"
    targetNamespace="http://foo.org/importvalidator.xsd    ← DELETE THIS"
    xmlns="http://foo.org/importvalidator.xsd"
    xmlns:mstns="http://foo.org/importvalidator.xsd"
    xmlns:xs="http://www.w3.org/2001/XMLSchema">

Так это выглядит так:

<xs:schema id="importvalidator"
    elementFormDefault="qualified"
    xmlns="http://foo.org/importvalidator.xsd"
    xmlns:mstns="http://foo.org/importvalidator.xsd"
    xmlns:xs="http://www.w3.org/2001/XMLSchema">

PS: кто-нибудь знает, если / как вы можете выделить части исходного кода с уценкой SO?

2 голосов
/ 31 мая 2009

@ 13ren имеет правильный ответ. Это не ошибка, если узел не соответствует ни одной схеме. Это только предупреждение. Я вижу предупреждения в коде ниже:

private static void ValidateDocument(XmlSchemaSet schemas, string uri)
{
    var settings = new XmlReaderSettings
                       {
                           Schemas = schemas,
                           ValidationFlags =
                               XmlSchemaValidationFlags.
                                   ProcessIdentityConstraints |
                               XmlSchemaValidationFlags.
                                   ReportValidationWarnings,
                           ValidationType = ValidationType.Schema
                       };
    settings.ValidationEventHandler += OnValidationEventHandler;
    using (var validatingReader = XmlReader.Create(uri, settings))
    {
        XDocument.Load(
            validatingReader,
            LoadOptions.SetBaseUri | LoadOptions.SetLineInfo);
    }
    return;
}

Это производит следующее:

Предупреждение. Не удалось найти информацию о схеме для элемента «jobs». Предупреждение: не удалось найти информацию о схеме для элемента 'job'. Предупреждение: не удалось найти информацию о схеме для элемента 'id'. Предупреждение: не удалось найти информацию о схеме для элемента «состояние». Предупреждение: не удалось найти информацию о схеме для элемента 'job'. Предупреждение: не удалось найти информацию о схеме для элемента 'id'.

Изменение вашего XML и запуск снова:

<?xml version="1.0" encoding="utf-8" ?>
<jobs xmlns="http://foo.org/importvalidator.xsd">
  <job>
    <id>1</id>
    <state><![CDATA[IL]]></state>
  </job>
  <job>
    <id>2</id>
  </job>
</jobs>

выдает ожидаемую ошибку:

Ошибка: элемент 'job' в пространстве имен 'http://foo.org/importvalidator.xsd' имеет неполное содержимое. Список возможных ожидаемых элементов: 'state' в пространстве имен 'http://foo.org/importvalidator.xsd'.

0 голосов
/ 31 мая 2009

Какой парсер / язык вы используете? Раньше вам приходилось сообщать анализатору Xerces, что вам нужна проверка XSD, если вы используете Java. Но после проверки документов последней версии я вижу, что проверка уже встроена. Так что, похоже, версия важна. Если вы являетесь разработчиком .NET, лучше всего проверить, какие его настройки должны быть.

Просто любопытно - почему CDATA окружает штат в вашем примере? Там нет необходимости, AFAIK. Вы даже можете вставить ограничение в свой XSD, чтобы получать только действительные коды штатов США.

Но обо всем по порядку - получите проверку схемы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...