Announcement Announcement Module
Collapse
No announcement yet.
XmlValidator won't complain about invalid XML Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • XmlValidator won't complain about invalid XML

    Hi,

    I'm trying to use XmlValidator programmatically in my test cases, but for some reason it won't detect invalid data.

    The test case below illustrates my problem. The XML used in testInValidXMLWithInvalidData() contains a string where the schema prescribes a float, but XmlValidator does not complain.

    The non-matching tags used in testInValidXMLWithNonMatchingTags() are detected by documentBuilder, so XmlValidator doesn't even get to look at that document.

    If anyone has any ideas, I'd appreciate it!

    Thanks,
    Dan


    Code:
    import java.io.StringReader;
    
    import javax.xml.parsers.DocumentBuilder;
    import javax.xml.parsers.DocumentBuilderFactory;
    import javax.xml.transform.dom.DOMSource;
    
    import junit.framework.TestCase;
    
    import org.springframework.core.io.ClassPathResource;
    import org.springframework.core.io.FileSystemResource;
    import org.springframework.xml.validation.XmlValidator;
    import org.springframework.xml.validation.XmlValidatorFactory;
    import org.w3c.dom.Document;
    import org.xml.sax.InputSource;
    
    public class XmlValidatorTest extends TestCase{
        
        private DocumentBuilder documentBuilder;
        private XmlValidator validator;
        
        public XmlValidatorTest() throws Exception{
            DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
            documentBuilderFactory.setNamespaceAware(true);
            documentBuilder = documentBuilderFactory.newDocumentBuilder();
            
            validator = XmlValidatorFactory.createValidator(new ClassPathResource("test.xsd"), XmlValidatorFactory.SCHEMA_W3C_XML);
        }
    
        // works as expected
        public void testValidXML() throws Exception {
    
            String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
            +"<testRequest xmlns=\"http://com.example/schemas/test\""
            +"    xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""
            +"    xsi:schemaLocation=\"http://com.example/schemas/test test.xsd\">"
            +"    <aString>hello</aString>"
            +"    <aFloat>1.5</aFloat>"
            +"</testRequest>";
            
            validate(xml);
        }
    
        // works as expected, non-matching tag detected by documentBuilder
        public void testInValidXMLWithNonMatchingTags() throws Exception {
            
            String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
                +"<testRequest xmlns=\"http://com.example/schemas/test\""
                +"    xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""
                +"    xsi:schemaLocation=\"http://com.example/schemas/test test.xsd\">"
                +"    <aString>hello</aStri>"  // this should not validate
                +"    <aFloat>1.5</aFloat>"
                +"</testRequest>";
            
            try{
                validate(xml);
                fail("No exception caused by invalid XML");
            }
            catch(Exception e){
                // expected
            }
        }
    
        // fails, because string instead of float is not detected by validator
        public void testInValidXMLWithInvalidData() throws Exception {
            
            String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
                +"<testRequest xmlns=\"http://com.example/schemas/test\""
                +"    xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""
                +"    xsi:schemaLocation=\"http://com.example/schemas/test test.xsd\">"
                +"    <aString>hello</aString>XXX"
                +"    <aFloat>I'M INVALID!</aFloat>" // this should not validate
                +"</testRequest>";
            
            try{
                validate(xml);
                fail("No exception caused by invalid XML");
            }
            catch(Exception e){
                // expected
            }
        }
        
        private void validate(String xml) throws Exception{
            Document doc =  documentBuilder.parse(new InputSource(new StringReader(xml)));
            validator.validate(new DOMSource(doc));
        }
    }

    Code:
    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
        xmlns:tns="http://com.example/schemas/test" elementFormDefault="qualified"
        targetNamespace="http://com.example/schemas/test">
    
        <xs:element name="testRequest" type="tns:testType" />
        <xs:element name="testResponse" type="tns:testType" />
    
        <xs:complexType name="testType">
            <xs:sequence>
                <xs:element name="aString" type="xs:string" minOccurs="1" maxOccurs="1" />
                <xs:element name="aFloat" type="xs:float" minOccurs="1" maxOccurs="1" />
            </xs:sequence>
        </xs:complexType>
    </xs:schema>

  • #2
    XmlValidator throws XmlValidationException only if the source cannot be validated, when the validator cannot decide whether the source is valid XML or not. If the source is found to be invalid, no exception is thrown, but a list of errors is returned.

    To make your test case work, just inspect the errors list returned from validate() and throw an exception if it is not empty.

    Code:
        private void validate(String xml) throws Exception{
            Document doc =  documentBuilder.parse(new InputSource(new StringReader(xml)));
            SAXParseException[] errors = validator.validate(new DOMSource(doc));
            if(errors.length > 0) throw errors[0];
        }
    Regards,
    -Ralph.

    Comment

    Working...
    X