Я создаю несколько XML-файлов, которые должны соответствовать предоставленному мне xsd-файлу. Как я должен проверить их соответствие?
Переведено автоматически
Ответ 1
Библиотека Java runtime поддерживает проверку. В последний раз, когда я проверял это, это был синтаксический анализатор Apache Xerces under the covers . Вероятно, вам следует использовать javax.xml.validation.Валидатор.
import javax.xml.XMLConstants; import javax.xml.transform.Source; import javax.xml.transform.stream.StreamSource; import javax.xml.validation.*; import java.net.URL; import org.xml.sax.SAXException; //import java.io.File; // if you use File import java.io.IOException; ... URLschemaFile=newURL("http://host:port/filename.xsd"); // webapp example xsd: // URL schemaFile = new URL("http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"); // local file example: // File schemaFile = new File("/location/to/localfile.xsd"); // etc. SourcexmlFile=newStreamSource(newFile("web.xml")); SchemaFactoryschemaFactory= SchemaFactory .newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); try { Schemaschema= schemaFactory.newSchema(schemaFile); Validatorvalidator= schema.newValidator(); validator.validate(xmlFile); System.out.println(xmlFile.getSystemId() + " is valid"); } catch (SAXException e) { System.out.println(xmlFile.getSystemId() + " is NOT valid reason:" + e); } catch (IOException e) {}
Константа фабрики схемы - это строка, http://www.w3.org/2001/XMLSchema которая определяет XSDSDS. Приведенный выше код проверяет дескриптор развертывания WAR на соответствие URL http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd но вы могли бы так же легко проверить на соответствие локальному файлу.
Вам не следует использовать DOMParser для проверки документа (если только вашей целью в любом случае не является создание объектной модели документа). При разборе документа начнется создание DOM-объектов - расточительно, если вы не собираетесь их использовать.
Ответ 2
Вот как это сделать с помощью Xerces2. Руководство по этому, здесь (см. регистрацию).
Поскольку это популярный вопрос, я укажу, что java также может проверять на соответствие "ссылочным" xsd-файлам, например, если сам XML-файл указывает XSD-файлы в заголовке, используя xsi:schemaLocation или xsi:noNamespaceSchemaLocation (или xsi для определенных пространств имен) например:
Другие ответы работают и здесь, потому что файлы .xsd "сопоставляются" с пространствами имен, объявленными в файле .xml, потому что они объявляют пространство имен, и если оно совпадает с пространством имен в файле .xml, все в порядке. Но иногда удобно иметь собственный распознаватель...
Из javadocs: "Если вы создаете схему без указания URL, файла или источника, то язык Java создает схему, которая ищет в проверяемом документе схему, которую он должен использовать. Например:"
и это работает для нескольких пространств имен и т.д. Проблема с этим подходом заключается в том, что xmlsns:xsi вероятно, это сетевое местоположение, поэтому по умолчанию оно будет выходить и попадать в сеть при каждой проверке, что не всегда оптимально.
Вот пример, который проверяет XML-файл на соответствие любым ссылкам XSD на it (даже если для этого приходится извлекать их из сети):
Вы можете избежать извлечения XSD-файлов, на которые ссылаются ссылки, из сети, даже если XML-файлы ссылаются на URL-адреса, указав xsd вручную (см. Некоторые Другие ответы Здесь) или используя распознаватель стилей "XML catalog". Spring, по-видимому, также может перехватывать запросы URL для обслуживания локальных файлов для проверки. Или вы можете установить свой собственный через setResourceResolver, например:
Source xmlFile = newStreamSource(xmlFileLocation); SchemaFactory schemaFactory = SchemaFactory .newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); Schema schema = schemaFactory.newSchema(); Validator validator = schema.newValidator(); validator.setResourceResolver(newLSResourceResolver() { @Override publicLSInputresolveResource(Stringtype, String namespaceURI, String publicId, String systemId, String baseURI) { InputSource is = newInputSource( getClass().getResourceAsStream( "some_local_file_in_the_jar.xsd")); // or lookup by URI, etc... returnnewInput(is); // for class Input see // https://javalang.ru/a/2342859/32453 } }); validator.validate(xmlFile);
Я полагаю, что по умолчанию используется синтаксический анализ DOM, вы можете сделать что-то подобное с SAX parser, который также проверяетsaxReader.setEntityResolver(your_resolver_here);