Проверка XML - использование нескольких xsd - PullRequest
10 голосов
/ 10 августа 2011

У меня есть два xsd-файла для проверки xml. Но проблема в том, что мой код использует только один xsd. Как использовать другой xsd в следующем коде? Я не имею представления о том, где я должен разместить / вызвать 2-й файл xsd.

             private void validate(File xmlF,File xsd1,File xsd2) {
                    try {
                        url = new URL(xsd.toURI().toString());//  xsd1
                    } catch (MalformedURLException e) {
                        e.printStackTrace();
                    }


                    source = new StreamSource(xml); // xml
                    try {
                        System.out.println(url);
                        schema = schemaFactory.newSchema(url);
                    } catch (SAXException e) {
                        e.printStackTrace();
                    }
                    validator = schema.newValidator();
                    System.out.println(xml);
                    try {
                        validator.validate(source);
                    } catch (SAXException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }

1 Ответ

25 голосов
/ 10 августа 2011

Множество хитов при поиске в SO или Google.Одним из них является этот вопрос, в котором автор нашел свое собственное решение и сообщает следующий код для добавления нескольких xsd в валидатор:

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

Однако при работе непосредственно с InputStream on StreamSource, распознаватель не может загрузить любые XSD-файлы, на которые есть ссылки.Например, если файл xsd1 импортирует или содержит третий файл (не xsd2), создание схемы завершится неудачно.Вы должны либо установить системный идентификатор (setSystemId), либо (что еще лучше) использовать конструктор StreamSource(File f).

С учетом вашего примера кода:

try {
  schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
  schema = schemaFactory.newSchema(new Source[] {
    new StreamSource(xsd1), new StreamSource(xsd2)
  });
} catch (SAXException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
}

Примечание:

При работе с ресурсами classpath я бы предпочел конструктор StreamSource(String systemId) (вместо создания File):

new StreamSource(getClass().getClassLoader().getResource("a.xsd").toExternalForm());
...