Pergunta

Eu estou procurando o melhor método para analisar vários documentos XML usando um aplicativo Java.Atualmente estou fazendo isso com o SAX e um conteúdo personalizado manipulador e ele funciona muito bem - zippy e estável.

Eu decidi explorar a opção de ter o mesmo programa, que atualmente recebe um único formato de documento XML, receber dois adicionais documento XML formatos, com vários elemento XML alterações.Eu estava esperando para trocar o ContentHandler com um apropriado com base no que o primeiro "startElement" no documento...mas, uh-duh, ContentHandler é definido e em seguida, o documento é analisado!

... constructor ...
{
SAXParserFactory spf = SAXParserFactory.newInstance();

try {
SAXParser sp = spf.newSAXParser();
parser = sp.getXMLReader();
parser.setErrorHandler(new MyErrorHandler());
} catch (Exception e) {} 

... parse StringBuffer ...
try {
parser.setContentHandler(pP);
parser.parse(new InputSource(new StringReader(xml.toString())));
return true;
} catch (IOException e) {
    e.printStackTrace();
} catch (SAXException e) {
    e.printStackTrace();
}
...

Assim, não parece que eu posso fazer isso da maneira que eu inicialmente pensei que eu poderia.

Dito isto, estou a olhar para esta totalmente errado?Qual é o melhor método para analisar múltiplos discretos de documentos XML com o mesmo XML o código de tratamento? Tentei fazer de uma forma mais geral post anterior...mas, eu acho que eu estava sendo muito vago.Para a velocidade e a eficiência meramente eu realmente nunca olhou para DOM porque esses documentos XML são bastante grandes e o sistema recebe cerca de 1200 a cada poucos minutos.É só uma forma de envio de informações

Para fazer esta pergunta muito tempo e adicionar à minha confusão;a seguir está uma maquete de alguns vários documentos XML que eu gostaria de ter um único SAX, StAX, ou ??analisador de forma limpa lidar com.

products.xml:

<products>
<product>
  <id>1</id>
  <name>Foo</name>
<product>
  <id>2</id>
  <name>bar</name>
</product>
</products>

stores.xml:

<stores>
<store>
  <id>1</id>
  <name>S1A</name>
  <location>CA</location>
</store>
<store>
  <id>2</id>
  <name>A1S</name>
  <location>NY</location>
</store>
</stores>

managers.xml:

<managers>
<manager>
  <id>1</id>
  <name>Fen</name>
  <store>1</store>
</manager>
<manager>
  <id>2</id>
  <name>Diz</name>
  <store>2</store>
</manager>
</managers>
Foi útil?

Solução

Como eu entendo, o problema é que você não sabe qual o formato do documento é anterior à análise.Você pode usar um delegado padrão.Eu estou supondo que você não está validando contra um DTD/XSD/etc e que é OK para o DefaultHandler ter estado.

public class DelegatingHandler extends DefaultHandler {

    private Map<String, DefaultHandler> saxHandlers;
    private DefaultHandler delegate = null;

    public DelegatingHandler(Map<String, DefaultHandler> delegates) {
        saxHandlers = delegates;
    }

    @Override
    public void startElement(String uri, String localName, String name,
            Attributes attributes) throws SAXException {
       if(delegate == null) {
           delegate = saxHandlers.get(name);
       }
       delegate.startElement(uri, localName, name, attributes);
    }

    @Override
    public void endElement(String uri, String localName, String name)
            throws SAXException {
        delegate.endElement(uri, localName, name);
    }

//etcetera...

Outras dicas

Você fez um bom trabalho de explicar o que você quer fazer, mas não é por isso.Existem várias XML quadros que simplificam marshalling e unmarshalling objetos Java a partir de/para XML.

O mais simples é O Commons Digestor o que eu normalmente uso para analisar arquivos de configuração.Mas se você quer lidar com objetos Java, então você deve olhar para Castor, JiBX, JAXB, XMLBeans, XStream, ou algo semelhante.De rícino ou JiBX são meus dois favoritos.

Eu tentei o SAXParser uma vez, mas uma vez eu encontrei XStream Eu nunca fui de volta para ele.Com XStream você pode criar Objetos Java e convertê-los em XML.Enviar e usar XStream para recriar o objeto.Muito fácil de usar, rápido, e cria limpo XML.

De qualquer forma você tem que saber o que o seu vai para o receptor do arquivo XML.Você pode enviá-las através de diferentes formas de saber qual o analisador para usar.Ou ter um objeto de dados que pode conter tudo, mas apenas uma estrutura é preenchida (loja/produto/gestores).Talvez algo como:

public class DataStructure {

    List<ProductStructure> products;

    List<StoreStructure> stors;

    List<ManagerStructure> managers;

    ...

    public int getProductCount() {
        return products.lenght();
    }

    ...
}

E com XStream converter para XML de envio e, em seguida, recriar o objeto.Em seguida, faça o que quiser com ele.

Consulte a documentação para XMLReader.setContentHandler(), ele diz:

Aplicativos podem registrar um novo ou diferente do manipulador no meio de uma análise, e o analisador SAX deve começar a usar o novo processador imediatamente.

Portanto, você deve ser capaz de criar um SelectorContentHandler que consome eventos até o primeiro startElement o evento, com base no que altera o ContentHandler no leitor de XML, e passa o primeiro elemento de início do evento para o novo manipulador de conteúdo.Você apenas tem que passar o XMLReader para o SelectorContentHandler no construtor.Se você precisa de todos os eventos a serem passa para o vocabulário específico manipulador de conteúdo, SelectorContentHandler tem para armazenar em cache os eventos e, em seguida, passá-los, mas na maioria dos casos isto não é necessário.

Em uma nota lateral, eu tenho usado ultimamente XOM em quase todos os meus projetos para lidar com XML ja até agora, o desempenho não foi o problema.

JAXB.O Java Architecture for XML Binding.Basicamente, você cria um xsd definição de seu XML de layout (eu acredito que você também poderia usar um DTD).Em seguida, passar o XSD JAXB compilador o compilador cria classes Java para empacotar e desempacotar seu documento XML para objetos Java.É realmente simples.

BTW, há opções de linha de comando para jaxb para especificar o nome do pacote que você deseja colocar as classes resultantes, etc.

Se você quiser mais dinâmico tratamento, Stax abordagem provavelmente iria funcionar melhor do que Sax.Muito baixo nível, ainda;se você deseja abordagem mais simples, XStream e JAXB são os meus favoritos.Mas eles não necessitam de bastante rígida objetos para o mapa.

Concordo com StaxMan, que curiosamente quer que você use Stax.É puxar um analisador baseado em vez de o empurrar você está usando no momento.Isso exigiria algumas alterações significativas no código embora.

:-)

Sim, tenho um pouco de preconceito para com Stax.Mas como eu disse, muitas vezes, a ligação de dados é mais conveniente do que a solução de streaming.Mas se se trata de streaming que você quer, e não precisa de pipelining (de vários estágios de filtragem), Stax é mais simples do que SAX.

Mais uma coisa:tão bom quanto XOM é (wrt alternativas), frequentemente Modelo de Árvore não é a coisa certa para usar, se não estiver a lidar com "centrados em documentos xml" (~= páginas xhtml, docbook, abrir documentos do office).Para o intercâmbio de dados, arquivos de configuração, etc enlace de dados é mais prático, mais eficiente, mais natural.Basta dizer não para os modelos de árvore como DOM para esses casos de uso.Assim, JAXB, XStream, JibX são bons.Ou, para mais gosto adquirido, digestor, mamona, xmlbeans.

VTD-XML é conhecido por ser o melhor XML tecnologia de processamento para serviço pesado, para processamento de XML.Veja a referência abaixo para uma prova

http://sdiwc.us/digitlib/journal_paper.php?paper=00000582.pdf

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top