Validação de XML com Include no Schema XSD usando JAXP

2 respostas
SkyShining

Olá pessoal, estou com um problema aqui e gostaria de saber se alguém já passou por algo semelhante.

O caso é o seguinte:
Tenho um arquivo XML para ser validado por um arquivo de schema XSD utilizando a API Java JAXP.
Só que o arquivo XSD possui a tag include para pegar elementos de outro arquivo XSD.

No entanto, quando vou validar o documento XML com os arquivos XSD é lancada uma exceção, mas se ao invés de incluir o arquivo eu criar um XSD único o erro não ocorre.

Vou apresentando os códigos e comentando.

Pessoa.xsd

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
	xmlns:obj="http://domain.com/xsd" 
	targetNamespace="http://domain.com/xsd" 
	elementFormDefault="qualified">
	
	<xs:complexType name="Pessoa">
		<xs:sequence>        
			<xs:element name="nome" type="xs:string"/>
			<xs:element name="telefone" type="xs:string"/>
		</xs:sequence>
	</xs:complexType>
	
</xs:schema>

PessoaFisica.xsd

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
	xmlns:obj="http://domain.com/xsd" 
	targetNamespace="http://domain.com/xsd"
	elementFormDefault="qualified">
	
	<xs:include schemaLocation="Pessoa.xsd" />
	
	<xs:complexType name="PessoaFisica">
		<xs:complexContent>
			<xs:extension base="obj:Pessoa">
				<xs:sequence>        
					<xs:element name="cpf" type="xs:string"/>
				</xs:sequence>
			</xs:extension>
		</xs:complexContent>
	</xs:complexType>
	
</xs:schema>

Simple.xml

<?xml version="1.0" encoding="UTF-8"?>
<xsd:PessoaFisica 
	xsi:type="xsd:PessoaFisica"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:xsd="http://domain.com/xsd">
	<xsd:nome>Gabriel Oliveira</xsd:nome>
	<xsd:telefone>36589236</xsd:telefone>
	<xsd:cpf>[telefone removido]</xsd:cpf>
</xsd:PessoaFisica>

Método da classe

@Test
	public void testeSimples() throws SAXException, IOException {
		InputStream xml = TesteValidacao.class.getResourceAsStream("/Simple.xml");
		InputStream xsd1 = TesteValidacao.class.getResourceAsStream("/Pessoa.xsd");
		InputStream xsd2 = TesteValidacao.class.getResourceAsStream("/PessoaFisica.xsd");
		SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
		StreamSource src1 = new StreamSource(xsd1);
		StreamSource src2 = new StreamSource(xsd2);
		Source[] sources = new Source[] {src1, src2};
		Schema schema = factory.newSchema(sources);
		Validator v = schema.newValidator();
		v.validate(new StreamSource(xml));
	}

Erro lançado

org.xml.sax.SAXParseException: cvc-elt.4.2: Cannot resolve 'xsd:PessoaFisica' to a type definition for element 'xsd:PessoaFisica'.
	at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:195)
	at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.error(ErrorHandlerWrapper.java:131)
	at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:384)
	at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:318)
	at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator$XSIErrorReporter.reportError(XMLSchemaValidator.java:410)
	at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.reportSchemaError(XMLSchemaValidator.java:3165)
	at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.getAndCheckXsiType(XMLSchemaValidator.java:2467)
	at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.handleStartElement(XMLSchemaValidator.java:1922)
	at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.startElement(XMLSchemaValidator.java:685)
	at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.scanStartElement(XMLNSDocumentScannerImpl.java:400)
	at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl$NSContentDriver.scanRootElementHook(XMLNSDocumentScannerImpl.java:626)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:3095)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(XMLDocumentScannerImpl.java:921)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:648)
	at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:140)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:510)
	at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:807)
	at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:737)
	at com.sun.org.apache.xerces.internal.jaxp.validation.StreamValidatorHelper.validate(StreamValidatorHelper.java:144)
	at com.sun.org.apache.xerces.internal.jaxp.validation.ValidatorImpl.validate(ValidatorImpl.java:107)
	at javax.xml.validation.Validator.validate(Validator.java:127)
	at teste.TesteValidacao.testeSimples(TesteValidacao.java:38)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at org.junit.internal.runners.TestMethodRunner.executeMethodBody(TestMethodRunner.java:99)
	at org.junit.internal.runners.TestMethodRunner.runUnprotected(TestMethodRunner.java:81)
	at org.junit.internal.runners.BeforeAndAfterRunner.runProtected(BeforeAndAfterRunner.java:34)
	at org.junit.internal.runners.TestMethodRunner.runMethod(TestMethodRunner.java:75)
	at org.junit.internal.runners.TestMethodRunner.run(TestMethodRunner.java:45)
	at org.junit.internal.runners.TestClassMethodsRunner.invokeTestMethod(TestClassMethodsRunner.java:66)
	at org.junit.internal.runners.TestClassMethodsRunner.run(TestClassMethodsRunner.java:35)
	at org.junit.internal.runners.TestClassRunner$1.runUnprotected(TestClassRunner.java:42)
	at org.junit.internal.runners.BeforeAndAfterRunner.runProtected(BeforeAndAfterRunner.java:34)
	at org.junit.internal.runners.TestClassRunner.run(TestClassRunner.java:52)
	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:45)
	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)

Na minha avaliação o que ocorre é que quando a factoy vai criar um novo schema a partir dos 2 arquivos XSD não está ficando correto o novo schema gerado.

2 Respostas

Paulo_Silveira

Oi!

Experiemte usar outro target name space no segundo xsd (o da pessoa fisica) em vez de http://domain.com/xsd. E mude o prefixo tambem (entao passe a usar outroPrefixo:PessoaFisica). Creio que ele nao aceite isso… e ai vai sempre pegar o do primeiro arquivo que encontrar!

abracos

SkyShining

Oi Paulo, se eu usar um targetnamespace diferente em um dos arquivos xsd então eu terei que usar import ao invés de include, mas também já testei com ambos e o problema ainda persiste.

Quanto a mudança do prefixo, não entendi muito bem. Poderia explicar ou me dar um exemplo?

Abraços,

Criado 1 de abril de 2009
Ultima resposta 1 de abr. de 2009
Respostas 2
Participantes 2