sax xml dodawanie do listy elementów z ogólniejszego tagu

0

Hej
To moje pierwsze zetknięcie z biblioteką sax do parsowania xml.
Mój przykładowy xml wygląda tak:

<?xml version="1.0" encoding="UTF-8" ?>
<persons>
    <person>
        <name>Jan</name>
        <surname>Kowalski</surname>
        <age>12</age>
        <city>Lublin</city>
        <contacts>
            <phone>123123123</phone>
            <phone>654 765 765</phone>
            <email>[email protected]</email>
            <email>[email protected]</email>
        </contacts>
    </person>
    <person>
        <name>Adam</name>
        <surname>Nowak</surname>
        <city>Lublin</city>
        <contacts>
            <phone>123123123</phone>
            <email>[email protected]</email>
            <icq>12321</icq>
            <jabber>jbr</jabber>
        </contacts>
    </person>
</persons>

Za pomocą warunków:

        if(element.equalsIgnoreCase("phone")){

            customerTmp.getContacts().add(tmpValue);
        }
        if(element.equalsIgnoreCase("email")){

            customerTmp.getContacts().add(tmpValue);
        }
        if(element.equalsIgnoreCase("icq")){

            customerTmp.getContacts().add(tmpValue);
        }
        if(element.equalsIgnoreCase("jabber")){

            customerTmp.getContacts().add(tmpValue);
        }

poszczególne elementy dodają się do listy.
Jednak nie chciałbym na sztywno definiować warunków dla phone, jabber, email itp tylko chciałbym do listy contacts wrzucić wszystko (jako string) co znajduje się pomiędzy <contacts></contacts>.

Ma ktoś pomysł jak to osiągnąć?

0
  1. Towrzysz własny handler do tego SAXa
  2. W handlerze masz: startElement i endElement

Jeśli startElement="contact" to zapalasz sobie jakąś flagę, np. contact_processing=1
Jeśli endElement="contract", to gasisz flagę contact_processing=0

Jeśli startElement != contact to sprawdzasz czy przetwarzasz sekcję contact, jeśli tak to zapamiętujesz sobie jakiś klucz np. current_key=qName, a wartość w tagu pakujesz np. do jakiejś mapy.
Przy gaszeniu flagi contact_processing (w endElement), masz mapę: currentContact<Klucz,Wartosc> i te dane jakoś tam sobie dalej obrabiasz/sklejasz.

0

A jakiś pomysł jak sparsować element nie definiując na sztywno warunku element.equalsIgnoreCase("icq") tylko np. wszystkie inne tagi poza tymi które chce osobno obsłużyć (name, surname, age, phone, email, jabber)?

0

Hmm, trzymać zbiór tagów "spechalnych" i sprawdzać czy bieżąco przetwarzany tag (nie) należy do tego zbioru? Albo nie zrozumiałem o co Ci chodzi.

0

Chodzi o to że znam tylko 3 konkretne tagi które mogę sparsować z użyciem warunku element.equalsIgnoreCase("phone") i dodać do List<String> phoneContacts (i tak analogicznie dla email i jabbera).
Ale chciałbym także w jakiś sposób wszystkie inne napotkane tagi, wcześniej nie sprecyzowane wrzucić do kompletnie innej listy.

Żadnego zbioru z góry zrobić na chwilę obecną nie mogę bo zawsze może trafić się nowy tag i wtedy powinien wskoczyć do listy unknowsContacts.

0

Pogubiłem się. Skoro wiesz, że masz 3 tagi: phone, email, jabber, które chcesz wrzucić do Listy_a, to jak znajdujesz tag i nie ma go w zbiorze ['phone','email','jabber'], to wrzucasz do drugiej listy. To Ci nie wystarcza?

// inicjalizowane raz w handlerze 
Set<String> supported_tags = new HashSet<>(Arrays.asList("phone", "jabber","email"));

// gdzieś w endElement logika typu:
if (supported_tags.contains(tag_name)) {
	lista1.add(...)
} else {
	lista2.add(...)
}

Poza tym, nie ma czegoś takiego jak "nieznany tag". (gdzieś musisz mieć specyfikację tego co siedzi w XMLu, czyli schemę).

1 użytkowników online, w tym zalogowanych: 0, gości: 1