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
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?
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
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
Espero ter ajudado
Flwss