Как зайти в Даркнет?!
25th January, 01:11
5
0
Как в tkinter из поля ввода Entry получить значение в одну переменную и обновить строку кнопкой, затем получить ещё одно введённое значение и затем сложить их. Ниже пример кода
21st July, 19:00
893
0
Программа, которая создает фейковые сервера в поиске игровых серверов CS 1.6 Steam
21st March, 17:43
948
0
Очень долго работает Update запрос Oracle
27th January, 09:58
912
0
не могу запустить сервер на tomcat HTTP Status 404 – Not Found
21st January, 18:02
905
0
Где можно найти фрилансера для выполнения поступающих задач, на постоянной основе?
2nd December, 09:48
938
0
Разработка мобильной кроссплатформенной военной игры
16th July, 17:57
1724
0
период по дням
25th October, 10:44
3955
0
Пишу скрипты для BAS только на запросах
16th September, 02:42
3720
0
Некорректный скрипт для закрытия блока
14th April, 18:33
4613
0
прокидывать exception в блоках try-catch JAVA
11th March, 21:11
4381
0
Помогите пожалуйста решить задачи
24th November, 23:53
6086
0
Не понимаю почему не открывается детальное описание продукта
11th November, 11:51
4350
0
Нужно решить задачу по программированию на массивы
27th October, 18:01
4396
0
Метода Крамера С++
23rd October, 11:55
4309
0
помогите решить задачу на C++
22nd October, 17:31
4002
0
Помогите решить задачу на python с codeforces
22nd October, 11:11
4492
0
Python с нуля: полное руководство для начинающих
18th June, 13:58
2599
0
Как лучше всего проверить файл XML на соответствие файлу XSD?
Я создаю некоторые файлы xml, которые должны соответствовать файлу xsd, который был мне дан. Как лучше всего проверить их соответствие?
Библиотека времени выполнения Java поддерживает проверку. Последний раз, когда я проверял это, был парсер Apache Xerces под обложкой. Вам, вероятно, следует использовать javax.xml.validation.Validator .
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;
...
URL schemaFile = new URL("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.
Source xmlFile = new StreamSource(new File("web.xml"));
SchemaFactory schemaFactory = SchemaFactory
.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
try {
Schema schema = schemaFactory.newSchema(schemaFile);
Validator validator = 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 , которая определяет XSDs. Приведенный выше код проверяет дескриптор WAR deployment против URL http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd , но вы можете так же легко проверить его с помощью локального файла.
Вы не должны использовать DOMParser для проверки документа (если только ваша цель не состоит в создании объектной модели документа в любом случае). Это позволит начать создавать объекты DOM по мере анализа документа-расточительно, если вы не собираетесь их использовать.
Вот как это сделать с помощью Xerces2 . Учебник для этого, здесь (req. Регистрация).
Оригинальная атрибуция: откровенно скопировано отсюда :
import org.apache.xerces.parsers.DOMParser;
import java.io.File;
import org.w3c.dom.Document;
public class SchemaTest {
public static void main (String args[]) {
File docFile = new File("memory.xml");
try {
DOMParser parser = new DOMParser();
parser.setFeature("http://xml.org/sax/features/validation", true);
parser.setProperty(
"http://apache.org/xml/properties/schema/external-noNamespaceSchemaLocation",
"memory.xsd");
ErrorChecker errors = new ErrorChecker();
parser.setErrorHandler(errors);
parser.parse("memory.xml");
} catch (Exception e) {
System.out.print("Problem parsing the file.");
}
}
}
Мы строим наш проект с использованием ant, поэтому мы можем использовать задачу schemavalidate для проверки наших конфигурационных файлов:
<schemavalidate>
<fileset dir="${configdir}" includes="**/*.xml" />
</schemavalidate>
Теперь непослушные конфигурационные файлы не смогут выполнить нашу сборку!
http://ant.apache.org/manual/Tasks/schemavalidate.html
Поскольку это популярный вопрос, я отмечу, что java также может проверить против "referred to" xsd, например, если сам файл .xml указывает XSD в заголовке, используя xsi:SchemaLocation или xsi:noNamespaceSchemaLocation (или xsi для определенных пространств имен) . :
<document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://www.example.com/document.xsd">
...
или SchemaLocation (всегда список отображений пространства имен в xsd)
<document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:SchemaLocation="http://www.example.com/my_namespace http://www.example.com/document.xsd">
...
Другие ответы также работают здесь, потому что .xsd файлов "map" к пространствам имен, объявленным в файле .xml, потому что они объявляют пространство имен, и если совпадает с пространством имен в файле .xml, Вы хороши. Но иногда бывает удобно иметь собственный решатель ...
Из javadocs: "если вы создаете схему без указания URL, файла или источника, то язык Java создает тот, который ищет в проверяемом документе, чтобы найти схему, которую он должен использовать. Например:"
SchemaFactory factory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");
Schema schema = factory.newSchema();
и это работает для нескольких пространств имен и т. д.
Проблема с этим подходом заключается в том, что xmlsns:xsi , вероятно, является сетевым местоположением, поэтому по умолчанию он будет выходить и попадать в сеть с каждой проверкой, не всегда оптимальной.
Вот пример, который проверяет файл XML на любые ссылки it XSD (даже если он должен вытащить их из сети):
public static void verifyValidatesInternalXsd(String filename) throws Exception {
InputStream xmlStream = new new FileInputStream(filename);
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setValidating(true);
factory.setNamespaceAware(true);
factory.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaLanguage",
"http://www.w3.org/2001/XMLSchema");
DocumentBuilder builder = factory.newDocumentBuilder();
builder.setErrorHandler(new RaiseOnErrorHandler());
builder.parse(new InputSource(xmlStream));
xmlStream.close();
}
public static class RaiseOnErrorHandler implements ErrorHandler {
public void warning(SAXParseException e) throws SAXException {
throw new RuntimeException(e);
}
public void error(SAXParseException e) throws SAXException {
throw new RuntimeException(e);
}
public void fatalError(SAXParseException e) throws SAXException {
throw new RuntimeException(e);
}
}
Вы можете избежать вытягивания ссылочных XSD из сети, даже если файлы xml ссылаются на url, указав xsd вручную (см. некоторые другие ответы здесь) или используя распознаватель стилей "XML catalog" . По-видимому, Spring также может перехватывать запросы URL для обслуживания локальных файлов для проверки. Или вы можете установить свой собственный через setResourceResolver, ex:
Source xmlFile = new StreamSource(xmlFileLocation);
SchemaFactory schemaFactory = SchemaFactory
.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = schemaFactory.newSchema();
Validator validator = schema.newValidator();
validator.setResourceResolver(new LSResourceResolver() {
@Override
public LSInput resolveResource(String type, String namespaceURI,
String publicId, String systemId, String baseURI) {
InputSource is = new InputSource(
getClass().getResourceAsStream(
"some_local_file_in_the_jar.xsd"));
// or lookup by URI, etc...
return new Input(is); // for class Input see
// https://stackoverflow.com/a/2342859/32453
}
});
validator.validate(xmlFile);
Смотрите также здесь другой учебник.
Я считаю, что по умолчанию используется парсинг DOM, вы можете сделать что-то подобное с парсером SAX, который также проверяет saxReader.setEntityResolver(your_resolver_here);
Используя Java 7, Вы можете следовать документации, приведенной в описании пакета.
// parse an XML document into a DOM tree DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder(); Document document = parser.parse(new File("instance.xml")); // create a SchemaFactory capable of understanding WXS schemas SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); // load a WXS schema, represented by a Schema instance Source schemaFile = new StreamSource(new File("mySchema.xsd")); Schema schema = factory.newSchema(schemaFile); // create a Validator instance, which can be used to validate an instance document Validator validator = schema.newValidator(); // validate the DOM tree try { validator.validate(new DOMSource(document)); } catch (SAXException e) { // instance document is invalid! }
Еще один ответ: поскольку вы сказали, что вам нужно проверить файлы, которые вы создаете (пишете), вы можете проверить содержимое во время записи, а не сначала писать, а затем читать для проверки. Вероятно, вы можете сделать это с помощью JDK API для проверки Xml, если вы используете SAX-based writer: если это так, просто свяжите валидатор с помощью вызова 'Validator.validate(source, result)', где источник исходит из вашего writer, а результат-это то, куда должен идти вывод.
Кроме того, если вы используете Stax для записи контента (или библиотеку, которая использует или может использовать stax), Woodstox также может напрямую поддерживать проверку при использовании XMLStreamWriter. Вот запись в блоге , показывающая, как это делается:
Если у вас есть Linux-машина, вы можете использовать бесплатный инструмент командной строки SAXCount. Я нашел это очень полезным.
SAXCount -f -s -n my.xml
Он проверяет против dtd и xsd. 5s для файла размером 50 МБ.
В debian squeeze он находится в пакете "libxerces-c-samples".
Определение dtd и xsd должно быть в xml! Вы не можете настроить их отдельно.
Если вы создаете файлы XML программно, вы можете посмотреть на библиотеку XMLBeans . С помощью инструмента командной строки XMLBeans автоматически создаст и упакует набор объектов Java на основе XSD. Затем эти объекты можно использовать для построения документа XML на основе этой схемы.
Он имеет встроенную поддержку проверки схемы и может конвертировать Java объектов в документ XML и наоборот.
Castor и JAXB - это другие библиотеки Java, которые служат той же цели, что и XMLBeans.
Вы ищете инструмент или библиотеку?
Что касается библиотек, то в значительной степени фактическим стандартом является Xerces2 , который имеет как версии C++ , так и Java .
Однако будьте заранее предупреждены, что это тяжеловесное решение. Но опять же, проверка XML против XSD файлов - это довольно тяжелая проблема.
Что касается инструмента, чтобы сделать это для вас, XMLFox , кажется, достойное бесплатное решение, но не использовав его лично, я не могу сказать наверняка.
С JAXB вы можете использовать следующий код:
@Test
public void testCheckXmlIsValidAgainstSchema() {
logger.info("Validating an XML file against the latest schema...");
MyValidationEventCollector vec = new MyValidationEventCollector();
validateXmlAgainstSchema(vec, inputXmlFileName, inputXmlSchemaName, inputXmlRootClass);
assertThat(vec.getValidationErrors().isEmpty(), is(expectedValidationResult));
}
private void validateXmlAgainstSchema(final MyValidationEventCollector vec, final String xmlFileName, final String xsdSchemaName, final Class<?> rootClass) {
try (InputStream xmlFileIs = Thread.currentThread().getContextClassLoader().getResourceAsStream(xmlFileName);) {
final JAXBContext jContext = JAXBContext.newInstance(rootClass);
// Unmarshal the data from InputStream
final Unmarshaller unmarshaller = jContext.createUnmarshaller();
final SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
final InputStream schemaAsStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(xsdSchemaName);
unmarshaller.setSchema(sf.newSchema(new StreamSource(schemaAsStream)));
unmarshaller.setEventHandler(vec);
unmarshaller.unmarshal(new StreamSource(xmlFileIs), rootClass).getValue(); // The Document class is the root object in the XML file you want to validate
for (String validationError : vec.getValidationErrors()) {
logger.trace(validationError);
}
} catch (final Exception e) {
logger.error("The validation of the XML file " + xmlFileName + " failed: ", e);
}
}
class MyValidationEventCollector implements ValidationEventHandler {
private final List<String> validationErrors;
public MyValidationEventCollector() {
validationErrors = new ArrayList<>();
}
public List<String> getValidationErrors() {
return Collections.unmodifiableList(validationErrors);
}
@Override
public boolean handleEvent(final ValidationEvent event) {
String pattern = "line {0}, column {1}, error message {2}";
String errorMessage = MessageFormat.format(pattern, event.getLocator().getLineNumber(), event.getLocator().getColumnNumber(),
event.getMessage());
if (event.getSeverity() == ValidationEvent.FATAL_ERROR) {
validationErrors.add(errorMessage);
}
return true; // you collect the validation errors in a List and handle them later
}
}
Проверка по сетевым схемам
Source xmlFile = new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream("your.xml"));
SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = factory.newSchema(Thread.currentThread().getContextClassLoader().getResource("your.xsd"));
Validator validator = schema.newValidator();
validator.validate(xmlFile);
Проверка по локальным схемам
Автономная проверка XML с помощью Java
Мне нужно было проверить XML против XSD только один раз, поэтому я попробовал XMLFox. Я нашел это очень запутанным и странным. Справочные инструкции, казалось, не соответствовали интерфейсу.
В итоге я использовал LiquidXML Studio 2008 (v6), который был намного проще в использовании и сразу же знаком (UI очень похож на Visual Basic 2008 Express, который я часто использую). Недостаток: возможность проверки отсутствует в бесплатной версии, поэтому мне пришлось использовать 30-дневную пробную версию.