I'm trying to write a unit test that will validate an XML string document against an XSD. Note that the XSDs are stored on disk and the URLs used for the namespaces in the XML doc are not actually available via a web server.
Here is the code:
@Test
public void testValidateAgainstXSD() throws Exception {
String xmlDoc = MY_XML_DOC_SAMPLE;
File schemaFile = new File("/Users/philswenson/dev/optimize_l/modules/ae/staging/eda-eventtypes/Analysis/1.0/MeasurementResultStatistics.xsd");
Source xmlFile = new StreamSource(xmlDoc);
SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = schemaFactory.newSchema(schemaFile);
Validator validator = schema.newValidator();
try {
validator.validate(xmlFile);
System.out.println(xmlFile.getSystemId() + " is valid");
} catch (SAXException e) {
throw new RuntimeException(e);
}
}
When I run the test I get the error below. Any ideas on what I'm doing wrong?
java.net.MalformedURLException: no protocol: <?xml version="1.0" encoding="utf-8"?>
<p:MeasurementResultStatistics xmlns:p="http://namespaces.myco.com/EDA/Analysis/1.0"> <p:Average>5.0</p:Average>
<p:Minimum>0.1</p:Minimum>
<p:Maximum>10.3</p:Maximum>
<p:StandardDeviation>0.0</p:StandardDeviation>
<p:HourOfDay>7</p:HourOfDay>
<p:DayOfWeek>Mon</p:DayOfWeek>
<p2:MeasurementDefinition xmlns:p2="http://namespaces.myco.com/EDA/Analysis/1.0">
<p2:Name>TEST KPI NAME</p2:Name>
<p2:DisplayName>TEST DISPLAY NAME</p2:DisplayName>
<p2:Version>1</p2:Version>
<p2:MeasurementUnits>TEST UOM</p2:MeasurementUnits>
<p2:TimeInterval>10000</p2:TimeInterval>
</p2:MeasurementDefinition>
<p3:MeasurementMember xmlns:p3="http://namespaces.myco.com/EDA/Analysis/1.0">
<p3:Name>TEST MONITOR STRING ID</p3:Name>
<p3:DisplayName>TEST DISPLAY NAME</p3:DisplayName>
</p3:MeasurementMember>
</p:MeasurementResultStatistics>
at java.net.URL.<init>(URL.java:567)
at java.net.URL.<init>(URL.java:464)
at java.net.URL.<init>(URL.java:413)
at org.apache.xerces.impl.XMLEntityManager.setupCurrentEntity(Unknown Source)
at org.apache.xerces.impl.XMLVersionDetector.determineDocVersion(Unknown Source)
at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
at org.apache.xerces.jaxp.validation.StreamValidatorHelper.validate(Unknown Source)
at org.apache.xerces.jaxp.validation.ValidatorImpl.validate(Unknown Source)
at javax.xml.validation.Validator.validate(Validator.java:127)
at com.myco.optimize.monitor.engine.XSDValidatorTest.testValidateAgainstXSD(XSDValidatorTest.java:46)
The problem is this line in your code:
Source xmlFile = new StreamSource(xmlDoc);
As we can see in the documentation, that StreamSource constructor assumes the String argument is a URL, not XML content. So it's trying to interpret your XML as if it were a URL, and not surprisingly, the XML does not start with a valid protocol (such as "http:").
The solution is to use the StreamSource(Reader) constructor instead:
Source xmlFile = new StreamSource(new StringReader(xmlDoc));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With