XML должен быть проверен по нескольким схемам xsd

Я пишу XSD и код для проверки, поэтому у меня есть большой контроль здесь.

Я хотел бы иметь функцию загрузки, которая добавляет материал в мое приложение на основе XML-файла. Одна часть XML-файла должна быть проверена на соответствие различным схемам на основе одного из значений в другой его части. Вот пример для иллюстрации:

<foo>
  <name>Harold</name>
  <bar>Alpha</bar>
  <baz>Mercury</baz>
  <!-- ... more general info that applies to all foos ... -->

  <bar-config>
    <!-- the content here is specific to the bar named "Alpha" -->
  </bar-config>
  <baz-config>
    <!-- the content here is specific to the baz named "Mercury" -->
  </baz>
</foo>

В этом случае есть некоторый контролируемый словарь для содержания <bar>и я справлюсь с этой частью просто отлично. Затем, основываясь на значении bar, следует использовать соответствующую XML-схему для проверки содержимого bar-config. Аналогично для баз и баз-конфиг.

Код, выполняющий анализ / проверку, написан на Java. Не уверен, насколько зависит от языка решение.

В идеале решение позволило бы автору xml объявить соответствующие местоположения схемы и что-то еще, чтобы он / она мог проверить xml на лету в достаточно умном редакторе.

Также возможные значения для <bar> а также <baz> являются ортогональными, поэтому я не хочу делать это по расширению для всех возможных комбинаций bar / baz. Я имею в виду, что если существует 24 возможных значения / схемы столбца и 8 возможных значений / схем baz, я хочу иметь возможность записать 1 + 24 + 8 = 33 суммарных схем вместо 1 * 24 * 8 = 192 суммарных схем,

Кроме того, я бы предпочел НЕ разбивать bar-config и baz-config на отдельные xml-файлы, если это возможно. Я понимаю, что это может значительно облегчить все проблемы, поскольку каждый XML-файл будет иметь одну схему, но я пытаюсь выяснить, есть ли хорошее решение для одного XML-файла.

4 ответа

Решение

Я наконец понял это.

Прежде всего, в схеме foo элементы bar-config и baz-config имеют тип, который включает any элемент, как это:

<sequence>
    <any minOccurs="0" maxOccurs="1"
        processContents="lax" namespace="##any" />
</sequence>

В xml вы должны указать правильное пространство имен, используя xmlns атрибут дочернего элемента bar-config или baz-config, например:

<bar-config>
    <config xmlns="http://www.example.org/bar/Alpha">
        ... config xml here ...
    </config>
</bar-config>

Затем ваш файл XML-схемы для панели Alpha будет иметь целевое пространство имен http://www.example.org/bar/Alpha и определит корневой элемент. config,

Если в вашем XML-файле есть объявления пространства имен и расположения схем для обоих файлов схемы, этого достаточно, чтобы редактор выполнил всю проверку (по крайней мере, достаточно для Eclipse).

До сих пор мы выполнили требование, чтобы автор xml мог написать xml таким образом, чтобы он был проверен в редакторе.

Теперь нам нужно, чтобы потребитель мог проверить. В моем случае я использую Java.

Если по какой-то случайности вы знаете файлы схемы, которые вам нужно будет использовать для предварительной проверки, то вы просто создаете один объект Schema и проверяете, как обычно, следующим образом:

Schema schema = factory().newSchema(new Source[] {
    new StreamSource(stream("foo.xsd")),
    new StreamSource(stream("Alpha.xsd")),
    new StreamSource(stream("Mercury.xsd")),
});

Однако в этом случае мы не знаем, какие xsd-файлы использовать, пока не проанализируем основной документ. Итак, общая процедура заключается в следующем:

  1. Проверьте xml, используя только основную (foo) схему
  2. Определите схему, чтобы использовать, чтобы проверить часть документа
  3. Найдите узел, который является корнем части для проверки, используя отдельную схему
  4. Импортируйте этот узел в новый документ
  5. Подтвердите новый документ, используя другой файл схемы

Предостережение: кажется, что документ должен быть построен с учетом пространства имен, чтобы это работало.

Вот некоторый код (он был скопирован из разных мест моего кода, поэтому при копировании и вставке могут быть некоторые ошибки):

// Contains the filename of the xml file
String filename;

// Load the xml data using a namespace-aware builder (the method 
// 'stream' simply opens an input stream on a file)
Document document;
DocumentBuilderFactory docBuilderFactory =
    DocumentBuilderFactory.newInstance();
docBuilderFactory.setNamespaceAware(true);
document = docBuilderFactory.newDocumentBuilder().parse(stream(filename));

// Create the schema factory
SchemaFactory sFactory = SchemaFactory.newInstance(
    XMLConstants.W3C_XML_SCHEMA_NS_URI);

// Load the main schema
Schema schema = sFactory.newSchema(
    new StreamSource(stream("foo.xsd")));

// Validate using main schema
schema.newValidator().validate(new DOMSource(document));

// Get the node that is the root for the portion you want to validate
// using another schema
Node node= getSpecialNode(document);

// Build a Document from that node
Document subDocument = docBuilderFactory.newDocumentBuilder().newDocument();
subDocument.appendChild(subDocument.importNode(node, true));

// Determine the schema to use using your own logic
Schema subSchema = parseAndDetermineSchema(document);

// Validate using other schema
subSchema.newValidator().validate(new DOMSource(subDocument));

Взгляните на NVDL (язык диспетчеризации на основе пространства имен) - http://www.nvdl.org/

Он предназначен для того, чтобы делать то, что вы хотите (проверять части документа XML, которые имеют свои собственные пространства имен и схемы).

Здесь есть учебное пособие - http://www.dpawson.co.uk/nvdl/ - и реализация Java здесь - http://jnvdl.sourceforge.net/

Надеюсь, это поможет! Kevin

Вам необходимо определить целевое пространство имен для каждой отдельно проверенной части экземпляра документа. Затем вы определяете основную схему, которая использует <xsd:include> для ссылки на документы схемы для этих компонентов.

Ограничением этого подхода является то, что вы не можете позволить отдельным компонентам определять схемы, которые должны использоваться для их проверки. Но в целом плохая идея - разрешать документу указывать, как его проверять (т. Е. Валидация должна выполняться под управлением вашего приложения).

Вы также можете использовать "распознаватель ресурсов", чтобы позволить "авторам xml" указать свой собственный файл схемы, по крайней мере, до некоторой степени, например: /questions/29279439/kakov-nailuchshij-sposob-proverki-xml-fajla-po-sravneniyu-s-xsd-fajlom/29279441#29279441 в конце дня, вам нужен полностью совместимый XML-файл, который в любом случае можно проверить с помощью обычных инструментов:)

Другие вопросы по тегам