Validacao xml / xsd

oi pessoal

tenho um arquivo xml e estou validando ele com um xsd e quando ocorre um erro de validacao gostaria de
transformar esse elemento em um objeto. alguem pode me ajudar?

obrigada

Como você está fazendo a leitura do xml?
Já tentou usar a biblioteca XStream? Ela gera uma XStreamException quando não consegue fazer o deserialize do objeto.

Att,

dou um parse no arquivo e trato com SAXParseException, no momento que ocorre a exception ele diz qual a tag que ocorreu o erro, por exemplo ‘cMun’, só que pode ter várias tags desse tipo para elementos diferentes… eu consigo tranformar esse elemento que deu o erro em objeto?
não manjo de xml, se estiver falando alguma bobagem por favor me corrige.

abraço

Bom, vamos ver se eu entendi o problema…
O que você poderia fazer é criar um contador para os elementos. Não sei que biblioteca você está utilizando, mas acredito que deva ter um método que retorne um nó em uma determinada posição.
Ex:

NodeList list = seuxml.getElements, //ou getElementsByTagName, algo do tipo Element elemento = (Element) list.item(0);

Com isso você pode pegar a posição do elemento que deu erro no seu catch e transformá-lo para um objeto Element.
Lembrando que nesse caso, se list.item(0) tiver filhos, elemento permitirá que você os acesse.

Você também pode obter um node e ler o seu valor, fica a seu critério.

Node no = (Node) list.item(0); String str = no.getNodeValue();

Ficou claro? :smiley:

Abraço.

Tenho um proj. free chamado OpenSutils-Br4J e lá tem isso já pronto, se quizer olhar o codigo ou baixar os jar tem no google.code… no link abaixo:

http://code.google.com/p/opensutils-br4j/wiki/XMLUtils

o nome do método é validateXML
e os erros ficam contidos na exception que o metodo lança se tiver com erro, o unico detalhe é que o xsd tem que estar em uma url, pode ser localhost. Agora se o xsd estiver em arquivo local, (sem url web) o método não consegue localizar o xsd, ficando para a prox versão.

no forum tb tem + info…
http://www.guj.com.br/java/225445-opensutils-br4j—biblioteca-de-utilitarios-utils

obrigada :slight_smile:

os elementos eu estou conseguindo pegar com o exemplo passado, o problema é que agora não consigo pegar o elemento que deu excecao, ou seja aquele q n passou na validacao :S

alguem? :S

Tenta fazer um teste…
Eu não tenho como rodar xml em java aqui onde trabalho, mas fiz um teste com exceção e consegui realizar o feito.
Não sei se ao dar uma exceção no xml ele invalida o objeto, por isso faça o teste como eu fiz, crie um “backup” do seu objeto que contém o xml. O código está em C#, mas você não vai ter problemas para entender.


using System;
using System.Collections.Generic;
using System.Text;

namespace ConsoleApplication1
{
    public class Class1
    {
        private List<int> teste;
        private List<int> teste2;
        private int errorIndex;

        public Class1(int times)
        {
            teste = new List<int>(times);
            teste2 = new List<int>(times);
            for (int i = 0; i < times; i++)
            {
                teste.Add(i);
            }
        }

        public void Teste()
        {
            for (int i = 0; i < teste.Count; i++)
            {
                try
                {
                    teste2.Add(teste[i]);
                    errorIndex = i;
                    if (i == 5)
                    {
                        throw new Exception();
                    }
                }
                catch (Exception)
                {
                    Console.WriteLine("Erro na linha: " + teste2[errorIndex]);
                    Console.Read();
                }

            }
        }


    }
}

Att,

ve se ajuda a ter uma ideia…
http://opensutils-br4j.googlecode.com/svn/OpenSutils-Br4J/src/org/opensutils/xml/XMLSchemaValidate.java

oie

esse link esta fazendo o mesmo que eu ja estava fazendo aqui, pegando apenas os erros, mas não onde esta o erro :S
eu estendi a classe DefaultHandler, dessa forma consegui pegar alguns eventos importantes
das tags no parse, porem ainda n consegui pegar extamente qual é a tag onde ocorre a exception…

alguem sabe se atraves do xstream eu consigo popular uma classe com os dados do xml?
se a resposta for sim, tem algum exemplo?

abraço

Olá Gisele

Talvez esse link sirva: http://java.sun.com/developer/technicalArticles/xml/validationxpath/

O Xtream, é bastante interessante. Porém é um destruidor de memória !!!

Para desparsear precisa ser exatamente o objeto que o “server” enviou, até o path (br.com…)…
Não gostei muito disto, quando trabalhei com xtream.

Creio que o Sax já te ajude.

Espero ter ajudado.

Flws

Editado: Exemplo de xtream: http://xstream.codehaus.org/tutorial.html

Gisele,

Validação feita pelo SAX…

Um exemplo de XSD

<?xml version="1.0" encoding="ISO-8859-1"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

	<xs:element name="howto">
		<xs:complexType>
			<xs:sequence>
				<xs:element name="topic" maxOccurs="unbounded">
					<xs:complexType>
						<xs:sequence>
							<xs:element name="title" type="xs:string" />
							<xs:element name="number" type="xs:integer" />
							<xs:element name="url" type="httpURI" />
						</xs:sequence>
					</xs:complexType>
				</xs:element>
			</xs:sequence>
		</xs:complexType>
	</xs:element>

	<xs:simpleType name="httpURI">
		<xs:restriction base="xs:anyURI">
			<xs:pattern value="http://.*" />
		</xs:restriction>
	</xs:simpleType>

</xs:schema>

Um exemplo do XML baseado neste XSD

<?xml version="1.0" encoding="ISO-8859-1"?>
<howto xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="howto howto.xsd">
	<topic>
		<title>Java</title>
		<number>10</number>
		<url>http://www.rgagnon.com/topics/java-xml.html</url>
	</topic>
	<topic>
		<title>PowerBuilder</title>
		<number>12</number>
		<url>http://www.rgagnon.com/topics/pb-powerscript.htm</url>
	</topic>
	<topic>
		<title>Javascript</title>
		<number>1</number>
		<url>http://www.rgagnon.com/topics/js-language.html</url>
	</topic>
	<topic>
		<title>VBScript</title>
		<number>8</number>
		<url>http://www.rgagnon.com/topics/wsh-vbs.html</url>
	</topic>
</howto>

Classe java validando, note que usei o XMLReader, mas também posso não usar.

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.EntityResolver;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;

public class SAXValidationXML {

	private static final String URI_VALIDATION = "http://xml.org/sax/features/validation";
	private static final String URI_SCHEMA = "http://apache.org/xml/features/validation/schema";

	private static final String SCHEMA_LANGUAGE = "http://java.sun.com/xml/jaxp/properties/schemaLanguage";
	private static final String SCHEMA_SOURCE = "http://java.sun.com/xml/jaxp/properties/schemaSource";
	private static final String XML_SCHEMA = "http://www.w3.org/2001/XMLSchema";

	private static final String FILE_XML = "howto.xml";
	private static final String FILE_SCHEMA = "howto.xsd";

	public SAXValidationXML() throws ParserConfigurationException, SAXException, IOException {
		SAXParserFactory spf = SAXParserFactory.newInstance();
		spf.setNamespaceAware(true);
		spf.setValidating(true);
		spf.setFeature(URI_VALIDATION, true);
		spf.setFeature(URI_SCHEMA, true);

		SAXParser sp = spf.newSAXParser();
		sp.setProperty(SCHEMA_LANGUAGE, XML_SCHEMA);
		sp.setProperty(SCHEMA_SOURCE, getFileInput(FILE_SCHEMA));

		
		//XMLReader só valida.
		XMLReader xmlReader = sp.getXMLReader();
		xmlReader.setErrorHandler(new EHandler());
		xmlReader.setEntityResolver(new EResolver());
		xmlReader.parse(new InputSource(getFileInput(FILE_XML)));
		
		//Se quiser usar para parsear o XML/Validar
		//sp.parse(getFileInput(FILE_XML), new DHandler());
	}

	public static void main(String[] args) {
		try {
			new SAXValidationXML();
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		} catch (SAXException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private class DHandler extends DefaultHandler {

		@Override
		public void startElement(String uri, String localName, String qName,
				Attributes attributes) throws SAXException {
			super.startElement(uri, localName, qName, attributes);
			System.out.println("QName " + qName);

		}
		
		/*
		 * Se preferir pode usar essa classe e implementar os metodos
		 * resolveEntity
		 * error
		 * warning
		 * fatalerror
		 * 
		 * Implementando esses metodos não precisa utilizar o XMLREADER.
		 * 
		 */
		
		@Override
		public InputSource resolveEntity(String publicId, String systemId) throws IOException, SAXException {
			return new InputSource(getFileInput(FILE_XML));
		}
		
		@Override
		public void error(SAXParseException e) throws SAXException {
			System.out.println("Main.ParserHandler.error()");
			System.err.println(e.getLineNumber() + ", " + e.getColumnNumber());
		}

		@Override
		public void warning(SAXParseException e) throws SAXException {
			System.out.println("Main.ParserHandler.warning()");
		}

		@Override
		public void fatalError(SAXParseException e) throws SAXException {
			System.out.println("Main.ParserHandler.fatalError()");
		}

	}
	
	
	//Essas duas classe são usadas somente para o XMLREADER.
	
	private class EResolver implements EntityResolver {
		@Override
		public InputSource resolveEntity(String publicId, String systemId)
				throws IOException, SAXException {
			return new InputSource(getFileInput(FILE_XML));
		}
	}

	private class EHandler implements ErrorHandler {

		@Override
		public void error(SAXParseException e) throws SAXException {
			System.out.println("Main.ParserHandler.error()");
			System.err.println(e.getLineNumber() + ", " + e.getColumnNumber());
		}

		@Override
		public void warning(SAXParseException e) throws SAXException {
			System.out.println("Main.ParserHandler.warning()");
		}

		@Override
		public void fatalError(SAXParseException e) throws SAXException {
			System.out.println("Main.ParserHandler.fatalError()");
		}

	}

	private InputStream getFileInput(String name) throws FileNotFoundException {
		return new FileInputStream(new File(name));
	}

}

Anexei também o projeto para fazer testes.

Olhando mais um pouco sobre validações de xml e xsd, vi que tem uma API para isso, XMLBeans.
Não testei, mas vi que é uma ferramenta bastante poderosa.
Vale a pena dar uma espiada nela…

Segue os links

  1. http://javafree.uol.com.br/topic-851661-Validar-XML-com-SCHEMA.html
  2. http://emarineli.wordpress.com/2009/06/25/validacoes-poderosas-com-o-apache-xmlbeans/
  3. http://www.guj.com.br/java/32063-aprendendo-apache-xmlbeans
  4. http://robsonp.com/01/2011/xml-com-xmlbeans/

Espero ter ajudado
Flwss