Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

troubles validating XML against XSD (java)

Tags:

java

xml

xsd

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)
like image 769
phil swenson Avatar asked Dec 15 '22 06:12

phil swenson


1 Answers

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));
like image 139
VGR Avatar answered Jan 03 '23 03:01

VGR