जवाबों:
जावा रनटाइम लाइब्रेरी सत्यापन का समर्थन करता है। पिछली बार मैंने जाँच की थी कि यह कवर के नीचे अपाचे ज़ेरिस पार्सर था। आपको शायद 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 को परिभाषित करता है। उपरोक्त कोड URL के विरुद्ध WAR परिनियोजन वर्णक को मान्य करता है, http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd
लेकिन आप स्थानीय फ़ाइल के विरुद्ध आसानी से मान्य कर सकते हैं।
आपको किसी दस्तावेज़ को मान्य करने के लिए DOMParser का उपयोग नहीं करना चाहिए (जब तक कि आपका लक्ष्य किसी भी तरह दस्तावेज़ ऑब्जेक्ट मॉडल बनाना नहीं है)। यदि आप दस्तावेज़ का उपयोग नहीं करते हैं तो यह DOM ऑब्जेक्ट बनाना शुरू कर देगा - बेकार।
यहाँ यह Xerces2 का उपयोग करके कैसे करना है । इसके लिए एक ट्यूटोरियल, यहां (req। साइनअप)।
मूल विशेषता: यहाँ से blatantly कॉपी किया गया :
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.");
}
}
}
हम चींटी का उपयोग करके अपनी परियोजना का निर्माण करते हैं, इसलिए हम अपनी विन्यास फाइल की जाँच करने के लिए योजनाबद्ध कार्य का उपयोग कर सकते हैं:
<schemavalidate>
<fileset dir="${configdir}" includes="**/*.xml" />
</schemavalidate>
अब शरारती कॉन्फिग फाइल्स हमारे बिल्ड को फेल कर देंगी!
चूँकि यह एक लोकप्रिय प्रश्न है, मैं यह इंगित करूँगा कि java उदाहरण के लिए "xsd" के लिए "संदर्भित" के विरुद्ध भी मान्य कर सकता है, यदि .xml फ़ाइल स्वयं हेडर में XSD का उपयोग करती है, xsi:SchemaLocation
या xsi:noNamespaceSchemaLocation
विशेष नामस्थान के लिए xsi निर्दिष्ट करती है : ex :
<document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://www.example.com/document.xsd">
...
या स्कीमालैक्शन (हमेशा xpd मैपिंग के लिए नामस्थान की सूची)
<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 फाइलें .xml फाइल में घोषित नामस्थानों के लिए "मैप" करती हैं, क्योंकि वे एक नेमस्पेस घोषित करते हैं, और अगर .xml फाइल में नाम स्थान के साथ मेल खाते हैं, तो आप अच्छे हैं। लेकिन कभी-कभी यह कस्टम रिज़ॉल्वर रखने में सक्षम होने के लिए सुविधाजनक होता है ...
Javadocs से: "यदि आप एक URL, फ़ाइल, या स्रोत को निर्दिष्ट किए बिना एक स्कीमा बनाते हैं, तो जावा भाषा वह बनाता है जो दस्तावेज़ में वैसा ही दिखता है जिसे स्कीमा को खोजने के लिए मान्य किया जाना चाहिए। उदाहरण के लिए:"
SchemaFactory factory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");
Schema schema = factory.newSchema();
और यह कई नामस्थानों के लिए काम करता है, आदि। इस दृष्टिकोण के साथ समस्या यह है कि xmlsns:xsi
यह संभवतः एक नेटवर्क स्थान है, इसलिए यह डिफ़ॉल्ट रूप से बाहर निकल जाएगा और नेटवर्क को प्रत्येक सत्यापन के साथ हिट करेगा, हमेशा इष्टतम नहीं।
यहां एक उदाहरण है जो किसी भी XSD के संदर्भों के विरुद्ध XML फ़ाइल को मान्य करता है (भले ही उसे नेटवर्क से खींचना पड़े):
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 कैटलॉग" स्टाइल रिज़ॉल्वर का उपयोग करके । वसंत जाहिरा तौर पर मान्यताओं के लिए स्थानीय फ़ाइलों की सेवा के लिए 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);
एक अन्य ट्यूटोरियल के लिए यहां भी देखें ।
मेरा मानना है कि डिफ़ॉल्ट रूप से, आप SAX पार्सर कि मान्य है के साथ इसी तरह कुछ कर सकते हैं डोम पार्स उपयोग करने के लिए है के रूप में अच्छी तरह से saxReader.setEntityResolver(your_resolver_here);
setResourceResolver
, लेकिन इसके अलावा, शायद नया सवाल खुला है ...
जावा 7 का उपयोग करके आप पैकेज विवरण में दिए गए प्रलेखन का पालन कर सकते हैं ।
// 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 StreamSource(new File("instance.xml")); } catch (SAXException e) { // instance document is invalid! }
parser.parse(new File("instance.xml"))
:। validator
एक को स्वीकार करता है Source
, तो आप कर सकते हैं: validator.validate(new StreamSource(new File("instance.xml")))
।
ErrorHandler
यदि आपको सत्यापन करने की आवश्यकता है तो यह प्रदान करना आवश्यक है ।
यदि आपके पास लिनक्स-मशीन है तो आप मुफ्त कमांड-लाइन टूल SAXCount का उपयोग कर सकते हैं। मुझे यह बहुत उपयोगी लगा।
SAXCount -f -s -n my.xml
यह dtd और xsd के विरुद्ध मान्य है। 50 एमबी फ़ाइल के लिए 5 एस।
डेबियन निचोड़ में यह पैकेज "लिबेक्सिसेस-सी-सैंपल" में स्थित है।
Dtd और xsd की परिभाषा xml में होनी चाहिए! आप उन्हें अलग से कॉन्फ़िगर नहीं कर सकते।
xmllint --schema phone.xsd phone.xml
(13ren द्वारा एक जवाब से) का उपयोग करें
एक और उत्तर: जब से आपने कहा था कि आपको उन फ़ाइलों को मान्य करने की आवश्यकता है जो आप (लेखन) उत्पन्न कर रहे हैं , तो हो सकता है कि आप लिखते समय सामग्री को मान्य करना चाहें, पहले लिखने के बजाय, फिर सत्यापन के लिए वापस पढ़ना। यदि आप SAX- आधारित लेखक का उपयोग करते हैं, तो आप शायद JDK API के साथ Xml सत्यापन के साथ ऐसा कर सकते हैं: यदि हां, तो बस 'Validator.validate (स्रोत, परिणाम)' कहकर लिंक करें, जहां स्रोत आपके लेखक से आता है, और परिणाम है जहां आउटपुट जाने की जरूरत है।
वैकल्पिक रूप से यदि आप लेखन सामग्री के लिए स्टैक्स का उपयोग करते हैं (या एक पुस्तकालय जो स्टैक्स का उपयोग करता है या उपयोग कर सकता है), तो वुडस्टॉक्स भी XMLStreamWriter का उपयोग करते समय सीधे सत्यापन का समर्थन कर सकता है। यहाँ एक ब्लॉग प्रविष्टि दिखाया गया है कि यह कैसे किया जाता है:
यदि आप XML फ़ाइलों को प्रोग्रामिक रूप से जनरेट कर रहे हैं, तो आप XMLBeans लाइब्रेरी को देखना चाह सकते हैं । कमांड लाइन टूल का उपयोग करते हुए, एक्सएमबी के आधार पर XMLBeans स्वचालित रूप से जावा ऑब्जेक्ट का एक सेट उत्पन्न और पैकेज करेगा। फिर आप इस ऑब्जेक्ट का उपयोग इस स्कीमा के आधार पर XML दस्तावेज़ बनाने के लिए कर सकते हैं।
इसमें स्कीमा सत्यापन के लिए अंतर्निहित समर्थन है, और जावा वस्तुओं को एक्सएमएल दस्तावेज़ में बदल सकता है और इसके विपरीत।
कैस्टर और JAXB अन्य जावा लाइब्रेरीज़ हैं जो XMLBeans के समान उद्देश्य को पूरा करती हैं।
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
}
}
आप एक उपकरण या एक पुस्तकालय के लिए देख रहे हैं?
जहाँ तक पुस्तकालयों की बात है, बहुत अधिक वास्तविक मानक Xerces2 है जिसमें C ++ और Java दोनों संस्करण हैं।
हालांकि, यह एक भारी वजन समाधान है चेतावनी दी हो। लेकिन तब फिर से, एक्सएसडी फाइलों के खिलाफ एक्सएमएल को मान्य करना एक भारी वजन की समस्या है।
आप के लिए ऐसा करने के लिए एक उपकरण के रूप में, XMLFox एक सभ्य फ्रीवेयर समाधान लगता है, लेकिन व्यक्तिगत रूप से इसका इस्तेमाल नहीं करने के लिए मैं निश्चित रूप से नहीं कह सकता।
ऑनलाइन स्कीमा के खिलाफ मान्य
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);
स्थानीय स्कीमाओं के खिलाफ मान्य
वुडस्टॉक्स का उपयोग करते हुए , अपने स्कीमा के खिलाफ मान्य करने के लिए Stax पार्सर को कॉन्फ़िगर करें और XML को पार्स करें।
यदि अपवाद पकड़ा जाता है तो XML मान्य नहीं है, अन्यथा यह मान्य है:
// create the XSD schema from your schema file
XMLValidationSchemaFactory schemaFactory = XMLValidationSchemaFactory.newInstance(XMLValidationSchema.SCHEMA_ID_W3C_SCHEMA);
XMLValidationSchema validationSchema = schemaFactory.createSchema(schemaInputStream);
// create the XML reader for your XML file
WstxInputFactory inputFactory = new WstxInputFactory();
XMLStreamReader2 xmlReader = (XMLStreamReader2) inputFactory.createXMLStreamReader(xmlInputStream);
try {
// configure the reader to validate against the schema
xmlReader.validateAgainst(validationSchema);
// parse the XML
while (xmlReader.hasNext()) {
xmlReader.next();
}
// no exceptions, the XML is valid
} catch (XMLStreamException e) {
// exceptions, the XML is not valid
} finally {
xmlReader.close();
}
नोट : यदि आपको कई फ़ाइलों को मान्य करने की आवश्यकता है, तो आपको प्रदर्शन को अधिकतम करने के लिए अपने XMLInputFactory
और पुन: उपयोग करने का प्रयास करना चाहिए XMLValidationSchema
।
मुझे एक्सएसडी के खिलाफ एक एक्सएमएल को केवल एक बार मान्य करना था, इसलिए मैंने एक्सएमएफएक्स की कोशिश की। मुझे यह बहुत भ्रामक और अजीब लगा। मदद निर्देश इंटरफ़ेस से मेल नहीं खाते।
मैंने LiquidXML Studio 2008 (v6) का उपयोग करना समाप्त कर दिया, जो कि उपयोग करने में बहुत आसान था और तुरंत परिचित था (UI विजुअल बेसिक 2008 एक्सप्रेस के समान है, जिसे मैं अक्सर उपयोग करता हूं)। खामी: सत्यापन की क्षमता नि: शुल्क संस्करण में नहीं है, इसलिए मुझे 30 दिन के परीक्षण का उपयोग करना पड़ा।