В прошлом я показывал вам, как анализировать XML с использованием подхода SAX и как улучшить синтаксический анализ вашего Android XML с помощью XML Pull . Оба эти метода работают, но довольно скучны, так как они квалифицируются как «сантехнический код». В этом уроке я собираюсь показать вам, как выполнить привязку XML в Android с помощью Simple Framework .
Привязка данных XML довольно популярна в Java, и существует множество платформ, которые позволяют связывание. Такие решения, как JAXB и XStream , хорошо известны и широко используются. Однако эти библиотеки занимают много места, что делает их неподходящими для использования в мире мобильных устройств с ограниченными ресурсами. Хорошей новостью является то, что в блоке появился новый ребенок, Простая структура . Как следует из его названия, он стремится внести некоторую простоту в раздутый мир XML.
С официального сайта Simple Framework:
Simple — это высокопроизводительная платформа XML-сериализации и конфигурации для Java. Его цель — предоставить структуру XML, которая обеспечивает быструю разработку систем конфигурации и связи XML. Эта структура помогает разработке систем XML с минимальными усилиями и уменьшением количества ошибок. Он предлагает полную сериализацию и десериализацию объектов, поддерживая каждую встреченную ссылку.
Очень хорошо. Вы можете начать работу с фреймворком, посетив страницу документации, и вам также следует прочитать, как JAXB сравнивается с Simple . Simple может изменить способ обработки XML в ваших Java-приложениях, попробуйте.
Большой вопрос заключается в том, поддерживается ли Simple в JVM Android. Android использует Dalvik , специализированную виртуальную машину, оптимизированную для мобильных устройств. Кроме того, Dalvik использует подмножество проекта Apache Harmony для ядра своей библиотеки классов . Не все основные классы Java поддерживаются. Например, некоторые из подпакетов javax.xml. * Не включены.
Ну, просто МОЖЕТ работать с Android. Более конкретно, мне удалось использовать версию 2.3.2, которую можно найти на странице загрузки Simple . Соответствующий JAR имеет размер 287KB. Примечания к выпуску для этой версии упоминают:
- Добавление поставщика DOM, так что StAX не является обязательной зависимостью
- Исправлена ошибка, из-за которой свойства по умолчанию правильно применялись к классам.
Первая проблема очень важна, потому что API StAX не включен в Android SDK . Обратите внимание, что последние версии Simple (после v2.3.2) также работают и могут использоваться для наших целей.
Давайте перейдем к погоне и посмотрим, как выполнить переплет. В качестве примера я буду использовать документ XML, который возвращается как ответ от API TMDb, который я использую в образце полного приложения Android, которое я создаю. Вот документ:
Поиск фильмов «Трансформеры» и (год) «2007»
Пример ответа также можно найти здесь .
Прежде всего загрузите Simple версию 2.3.2 и включите ее в путь к классам вашего проекта. Затем кратко рассмотрим простые рамки Javadocs .
Самое главное — создать объекты нашей модели и соответствующим образом отобразить документ в формате XML. Если мы посмотрим на файл XML, то увидим, что корневой элемент называется OpenSearchDescription и включает в себя элемент Query, элемент totalResults и несколько фильмов. Вот как выглядит наш основной класс модели:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
|
package com.javacodegeeks.xml.bind.model; import java.util.List; import org.simpleframework.xml.Element; import org.simpleframework.xml.ElementList; import org.simpleframework.xml.Root; @Root public class OpenSearchDescription { @Element (name= "Query" ) public Query query; @Element public int totalResults; @ElementList public List<Movie> movies; } |
Корневая аннотация обозначает, что определенный класс представляет корневой элемент XML. Мы также используем аннотации Element и ElementList для вложенных элементов. Обратите внимание, что Simple может обрабатывать подходы «getter / setters» и «public fields». Я использую последнее в этом примере. Следует помнить, что мы используем поле имени (для «запроса»), чтобы предоставить соответствующее имя элемента XML. Это следует делать, когда элемент XML имеет имя, отличное от поля Java, поскольку Simple по умолчанию ищет элемент с тем же именем, что и у поля.
Давайте теперь посмотрим класс Query:
01
02
03
04
05
06
07
08
09
10
11
12
|
package com.javacodegeeks.xml.bind.model; import org.simpleframework.xml.Attribute; import org.simpleframework.xml.Element; @Element public class Query { @Attribute public String searchTerms; } |
Этот класс содержит только атрибут с именем «searchTerms», поэтому соответствующее поле помечено атрибутом .
Очень легко до сих пор. Давайте проверим класс Movie:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
package com.javacodegeeks.xml.bind.model; import java.util.List; import org.simpleframework.xml.Element; import org.simpleframework.xml.ElementList; @Element (name= "movie" ) public class Movie { @Element (required= false ) public String score; @Element (required= false ) public String popularity; @Element (required= false ) public String name; @Element (required= false ) public String id; @Element (required= false ) public String biography; @Element (required= false ) public String url; @Element (required= false ) public String version; @Element (required= false ) public String lastModifiedAt; @ElementList public List<Image> images; } |
Единственным нововведением является то, что обязательное поле используется для того, чтобы объявить, что поле не является обязательным (может быть пустым). Это сделано потому, что некоторые поля в ответе API пусты.
Давайте посмотрим на класс Image:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
package com.javacodegeeks.xml.bind.model; import org.simpleframework.xml.Attribute; import org.simpleframework.xml.Element; @Element (name= "image" ) public class Image { @Attribute public String type; @Attribute public String url; @Attribute public String size; @Attribute public int width; @Attribute public int height; @Attribute public String id; } |
Этот класс включает только атрибуты, поэтому мы соответствующим образом аннотируем поля.
Последний шаг — прочитать исходный XML и позволить Simple подключить все классы и заполнить поля. Это делается с помощью класса Persister, который обеспечивает реализацию интерфейса Serializer . Мы будем использовать его метод read, который считывает содержимое XML-документа из предоставленного источника и преобразует его в объект указанного типа. Обратите внимание, что мы отключили строгий режим. Вот как это выглядит внутри Android Activity :
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
|
package com.javacodegeeks.xml.bind; import java.io.IOException; import java.io.Reader; import java.io.StringReader; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.util.EntityUtils; import org.simpleframework.xml.Serializer; import org.simpleframework.xml.core.Persister; import android.app.Activity; import android.os.Bundle; import android.util.Log; import android.widget.Toast; import com.javacodegeeks.xml.bind.model.OpenSearchDescription; public class SimpleExampleActivity extends Activity { private static final String url = private DefaultHttpClient client = new DefaultHttpClient(); @Override public void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.main); try { String xmlData = retrieve(url); Serializer serializer = new Persister(); Reader reader = new StringReader(xmlData); OpenSearchDescription osd = serializer.read(OpenSearchDescription. class , reader, false ); Log.d(SimpleExampleActivity. class .getSimpleName(), osd.toString()); } catch (Exception e) { Toast.makeText( this , "Error Occured" , Toast.LENGTH_LONG).show(); } } public String retrieve(String url) { HttpGet getRequest = new HttpGet(url); try { HttpResponse getResponse = client.execute(getRequest); final int statusCode = getResponse.getStatusLine().getStatusCode(); if (statusCode != HttpStatus.SC_OK) { return null ; } HttpEntity getResponseEntity = getResponse.getEntity(); if (getResponseEntity != null ) { return EntityUtils.toString(getResponseEntity); } } catch (IOException e) { getRequest.abort(); Log.w(getClass().getSimpleName(), "Error for URL " + url, e); } return null ; } } |
Это типичная активность Android . Мы извлекаем XML-документ как интернет-ресурс (см. Мое руководство по использованию HTTP API ), а затем создаем StringReader из ответа. Мы наполняем Serializer этим, а затем позволяем Simple выполнить его магию и возвращаем как полный класс с соответствующими полями и встроенными классами. Конкретное приложение просто сбросит строковые представления классов в системный журнал, который можно отслеживать в представлении DDMS.
Это все, ребята. Нет больше ручного синтаксического анализа XML для меня. Как всегда, вы можете скачать проект Eclipse, созданный для этого урока.
Счастливого Android-кодирования! И не забудьте поделиться!
Статьи по Теме: