Hvordan ville du bruke Java for å håndtere ulike XML-dokumenter?

stemmer
2

Jeg leter etter den beste metoden for å analysere ulike XML-dokumenter ved hjelp av en Java-applikasjon. Jeg er for tiden gjør dette med SAX og et tilpasset innhold handler og det fungerer bra - Zippy og stabil.

Jeg har bestemt meg for å utforske muligheten å ha det samme programmet, som i dag mottar et enkelt format XML-dokument, får to ekstra XML dokumentformater, med ulike XML element endringer. Jeg hadde håpet å bare bytte ut Content med en passende en basert på den første startElement i dokumentet ... men, uh-duh, det Content er satt, og deretter dokumentet analyseres!

... 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();
}
...

Så, betyr det ikke ut til at jeg kan gjøre dette på den måten jeg trodde først jeg kunne.

Når det er sagt, jeg ser på dette helt feil? Hva er den beste metoden for å analysere flere, diskrete XML dokumenter med samme XML håndtering koden? Jeg prøvde å spørre i en mer generell innlegg tidligere ... men, jeg tror jeg var å være for vag . For fart og effektivitet formål jeg egentlig aldri sett på DOM fordi disse XML-dokumenter er ganske store og systemet mottar ca 1200 med få minutters mellomrom. Det er bare en vei sending av informasjon

For å gjøre dette spørsmålet for lenge og legge til min forvirring; Følgende er en mockup av noen ulike XML-dokumenter som jeg ønsker å ha en enkelt SAX, Stax, eller ?? parser rent håndtere.

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>
Publisert på 27/08/2008 klokken 16:55
kilden bruker
På andre språk...                            


9 svar

stemmer
3

Som jeg forstår det, problemet er at du ikke vet hvilket format dokumentet er tidligere analyse. Du kan bruke en delegat mønster. Jeg antar du ikke validerer mot en DTD / XSD / etcetera, og at det er OK for DefaultHandler å ha staten.

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...
Svarte 27/08/2008 kl. 17:38
kilden bruker

stemmer
2

Se dokumentasjonen for XMLReader.setContentHandler () , står det:

Søknader kan registrere en ny eller annen behandler i midten av en analysere og SAX parser må begynne å bruke den nye handler umiddelbart.

Derfor bør du være i stand til å skape en SelectorContentHandlersom forbruker hendelser før den første startElementhendelsen, basert på som endrer ContentHandlerpå XML-leser, og går første start element hendelse til nytt innhold handler. Du trenger bare å passere XMLReadertil SelectorContentHandleri konstruktøren. Hvis du trenger alle hendelsene å være pass til vokabular spesifikke innholdet handler, SelectorContentHandlermå cache hendelsene og deretter sende dem, men i de fleste tilfeller er dette ikke nødvendig.

På en side note, har jeg i det siste brukt XOM i nesten alle mine prosjekter for å håndtere XML ja så langt resultatene har ikke vært problemet.

Svarte 27/08/2008 kl. 18:58
kilden bruker

stemmer
2

Jeg har prøvd SAXParser en gang, men når jeg fant Xstream jeg aldri gikk tilbake til det. Med Xstream kan du lage Java objekter og konvertere dem til XML. Send dem over og bruke Xstream å gjenskape objektet. Veldig enkel å bruke, rask, og skaper ren XML.

Uansett hva du trenger å vite hvilke data du kommer til mottaker fra XML-filen. Du kan sende dem over i ulike måter å vite hvilke parser å bruke. Eller har et dataobjekt som kan holde alt, men bare en struktur er befolket (produkt / store / ledere). Kanskje noe sånt som:

public class DataStructure {

    List<ProductStructure> products;

    List<StoreStructure> stors;

    List<ManagerStructure> managers;

    ...

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

    ...
}

Og med Xstream konvertere til XML sende over, og deretter gjenskape objektet. Så gjør hva du vil med den.

Svarte 27/08/2008 kl. 17:30
kilden bruker

stemmer
2

Du har gjort en god jobb med å forklare hva du ønsker å gjøre, men ikke hvorfor. Det er flere XML rammeverk som forenkler marshalling og unmarshalling Java-objekter til / fra XML.

Det enkleste er Commons Rötningskammare som jeg vanligvis bruker for å analysere konfigurasjonsfiler. Men hvis du ønsker å håndtere Java objekter så bør du se på Castor , JiBX , JAXB , XMLBeans , Xstream , eller noe lignende. Castor eller JiBX er mine to favoritter.

Svarte 27/08/2008 kl. 17:22
kilden bruker

stemmer
1

JAXB . Java Architecture for XML Binding. I utgangspunktet du oppretter en xsd definere XML layout (jeg tror du kan også bruke en DTD). Da passerer du XSD til JAXB kompilatoren og kompilatoren skaper Java klasser å skaffe til veie og unmarshal XML-dokument til Java objekter. Det er veldig enkelt.

BTW, det er kommandolinje alternativer for å JAXB å spesifisere pakkenavnet du ønsker å plassere de resulterende klasser i, etc.

Svarte 27/08/2008 kl. 17:20
kilden bruker

stemmer
0

VTD-XML er kjent for å være den beste XML behandlingsteknologi for heavy duty XML behandling. Se referanse under for et bevis

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

Svarte 09/04/2016 kl. 19:24
kilden bruker

stemmer
0

:-)

Ja, jeg har noen bias mot Stax. Men som jeg sa, ofte databinding er mer praktisk enn streaming løsning. Men hvis det er streaming du vil, og trenger ikke pipelining (av flere filtreringstrinn), er Stax enklere enn SAX.

En ting til: så godt som XOM er (wrt alternativer), er ofte treet Modellen er ikke den riktige tingen å bruke hvis du ikke har å gjøre med "dokument-sentrisk" xml (~ = XHTML-sider, docbook, åpne Office-dokumenter). For datautveksling, config filer etc databinding er mer praktisk, mer effektiv, mer naturlig. Bare si nei til tre modeller som DOM for disse bruksmåter. Så, JAXB, Xstream, JibX er gode. Eller, for mer ervervet smak, koker, trinse, XMLBeans.

Svarte 27/01/2009 kl. 20:26
kilden bruker

stemmer
0

Enig med StaxMan, som interessant nok vil at du skal bruke Stax. Det er en pull basert parser i stedet for push du bruker. Dette ville kreve noen betydelige endringer i koden selv.

Svarte 08/01/2009 kl. 14:32
kilden bruker

stemmer
0

Hvis du vil ha mer dynamiske kjøreegenskaper, ville Stax tilnærming sannsynligvis fungere bedre enn Sax. Det er ganske lavt nivå, likevel; Hvis du vil ha enklere tilnærming, Xstream og JAXB er mine favoritter. Men de krever ganske stive gjenstander for å kartlegge til.

Svarte 08/01/2009 kl. 04:00
kilden bruker

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more