Parsing — процес на синтактичен анализ на структурирани данни, който извлича информация от JSON, XML, CSV или Protobuf за използване в приложението. По данни на Square Engineering (2025), изборът на стратегия за парсинг пряко влияе върху производителността на мобилното приложение. Поточен парсинг позволява обработка на мегабайти данни без зареждане на целия документ в паметта.
Основни
Парсинг (синтактичен анализ) — процес на преобразуване на последователност от знаци в структурирано представяне, подходящо за програмна обработка. В контекста на мобилното разработване под парсинг се разбира анализ на сървърни отговори, конфигурационни файлове, локален кеш и ресурсни файлове. Всеки формат изисква собствен подход: JSON — лек и вграден в SDK, XML — строг с валидация на XSD схема, CSV — минималистичен за таблични данни, Protobuf — двоичен с твърда схема.
Всеки парсер, независимо от формата, преминава през три етапа. Лексикален анализ разделя суровия текст на лексеми: ключове, низове, числа, разделители и коментари. Синтактичен анализ проверява коректността на граматиката — баланс на скоби в JSON, правилно влагане на тагове в XML. Изграждане на изходна структура формира обектно представяне: JSONObject, Map или поток от токени за по-нататъшна обработка. По данни на Apple (2026), вграденият Foundation парсер на iOS използва ленив анализ — валидира само началото на JSON, спестявайки ресурси.
Ръчен парсинг (JSONSerialization, XmlPullParser) дава пълен контрол над процеса и е полезен при нестандартни формати или необходимост от персонализирана валидация на всяко поле. Автоматични библиотеки (JSONDecoder, Moshi, kotlinx.serialization) ускоряват разработката, но скриват детайлите на обработката на грешки. Изборът зависи от изискванията: ако структурата на данните е динамична или предварително неизвестна — ръчният парсинг е предпочитан. Ако схемата е фиксирана — автоматичната десериализация съкращава кода с 60–70%.
Парсинг — по-широка операция: може да се изпълнява потоково и не задължително създава типизиран обект. Десериализация — частен случай на парсинг, чийто резултат винаги е инстанция на предварително известен клас с конкретни типове свойства. JSON парсер ще разбие документа на Map или JsonElement, а десериализаторът ще превърне същия JSON в конкретен обект User, Order или Product с известни полета и техните типове.
| Характеристика | Парсинг | Десериализация |
|---|---|---|
| Резултат | JsonElement, Map, поток от токени | Типизиран обект (User, Order) |
| Поточен режим | Да (SAX, JsonReader) | Не (целият обект в паметта) |
| Типизация | Незадължителна, динамични типове | Задължителна, статични типове |
| Пример | XmlPullParser.next(), SAX events | json.decodeFromString<User>() |
Поточен парсинг — основното предимство на парсинга пред десериализацията. XmlPullParser на Android анализира XML докато чете, без да зарежда целия документ в оперативната памет. Това е критично за големи API отговори, парсинг на RSS канали със стотици елементи или обработка на масив от хиляди JSON обекти от сървърен дамп. Поточен парсер чете токен след токен, консумирайки постоянно количество памет независимо от размера на документа.
JSON — доминиращият формат за обмен на данни. На iOS вграденият JSONSerialization анализира JSON в Any, а JSONDecoder — директно в Codable структура. На Android стандартният org.json предоставя JSONObject и JSONArray за ръчен анализ. Gson и Moshi добавят автоматично преобразуване. Изборът между ръчен и автоматичен подход — първото архитектурно решение на мрежовия слой.
val jsonString = """{"users":[{"id":1,"name":"Alice"}]}"""
val jsonObject = JSONObject(jsonString)
val usersArray = jsonObject.getJSONArray("users")
for (i in 0 until usersArray.length()) {
val item = usersArray.getJSONObject(i)
val id = item.getInt("id")
val name = item.getString("name")
// обработка на потребител
}
Ръчен парсинг чрез org.json е полезен, когато структурата на отговора е предварително неизвестна или значително варира. Този подход дава пълен контрол над обработката на грешки и nullable полета, но изисква повече шаблонен код в сравнение с автоматичната десериализация. За малки проекти или прототипи е приемливо, но в production се препоръчва Moshi или kotlinx.serialization.
JsonReader от библиотеката Moshi — мощен инструмент за поточен JSON парсинг. Чете документа токен след токен, използвайки методите beginObject, nextName, nextString, nextInt и endObject. Този подход позволява обработка на документи с произволен размер с постоянно потребление на памет. По данни на Google (2026), поточният парсинг чрез JsonReader е 2–3 пъти по-бърз от зареждане на целия документ в JsonObject и консумира до 80% по-малко памет.
val reader = JsonReader(StringReader(json))
reader.beginObject()
while (reader.hasNext()) {
val name = reader.nextName()
when (name) {
"id" -> val id = reader.nextInt()
"name" -> val name = reader.nextString()
"email" -> val email = reader.nextString()
else -> reader.skipValue()
}
}
reader.endObject()
Примерът показва JsonReader, който анализира JSON потоково. Всяко извикване на nextName() и nextInt() премества курсора към следващия токен. skipValue() пропуска ненужни полета без анализ — това е особено полезно, когато JSON съдържа 50 полета, а са необходими само 3. Резултат — минимална консумация на памет и максимална скорост.
XML продължава да се използва в Android проекти за ресурси и в SOAP услуги на корпоративни приложения. На Android вграденият XmlPullParser осигурява поточен анализ с минимална консумация на памет — не зарежда DOM дърво, а генерира събития START_TAG, TEXT, END_TAG. iOS използва XMLParser с делегатен подход: методите parser(didStartElement:) и parser(foundCharacters:) обработват елементите последователно.
CSV — най-простият формат за експорт и импорт на таблични данни. В мобилни приложения CSV се използва за експорт на отчети, зареждане на справочници (списъци на държави, валути, кодове) и синхронизация на офлайн данни. За парсинг на CSV са подходящи поточни библиотеки: Apache Commons CSV и OpenCSV обработват файлове ред по ред, екранирайки кавички и запетаи вътре в стойностите. На iOS CSV парсинг може да се реализира чрез разделителя NSString.components(separatedBy:) с обработка на крайни случаи.
class CSVParser: NSObject, XMLParserDelegate {
private var currentItem: [String: String] = [:]
private var currentElement: String = ""
func parser(
_ parser: XMLParser,
didStartElement elementName: String,
namespaceURI: String?,
qualifiedName qName: String?,
attributes attributeDict: [String: String]
) {
currentElement = elementName
if elementName == "item" {
currentItem = [:]
}
}
func parser(_ parser: XMLParser,
foundCharacters string: String) {
currentItem[currentElement] = string
}
}
Пример за делегат на XMLParser на iOS за анализ на RSS канал. Методът didStartElement се извиква при всеки отварящ таг, foundCharacters връща текст съдържанието между таговете, didEndElement приключва елемента. Такава събитийно-базирана архитектура позволява обработка на XML с произволен размер без зареждане на DOM дървото в паметта — критично за ограничените ресурси на мобилни устройства.
На Android изборът на CSV парсер зависи от обема на данните. OpenCSV поддържа fluent API, анотации за картографиране към POJO и персонализирани разделители. Apache Commons CSV — по-ниско ниво, но по-бърз на големи файлове. За прости случаи (1–2 колони) е достатъчен ръчен анализ чрез String.split(",") с обработка на екраниране. За production проекти с големи CSV файлове се препоръчва OpenCSV.
Protocol Buffers от Google — двоичен формат за сериализация, превъзхождащ JSON по скорост и компактност. Protobuf съобщение заема 3–6 пъти по-малко място от еквивалентния JSON и се анализира 4–10 пъти по-бързо благодарение на двоичния формат и твърдата схема. Основни недостатъци: липса на човешка четмост и необходимост от генериране на код от .proto файлове чрез protoc компилатор.
Поточен парсинг на Protobuf се реализира чрез CodedInputStream — клиентът чете полетата при пристигането им без зареждане на цялото съобщение. Всяко поле има таг (номер + тип) и парсерът може да пропуска непознати полета. По данни на Google (2026), поточният анализ на Protobuf консумира до 90% по-малко памет при обработка на съобщения от 1 MB, което е критично за мобилни устройства с ограничена RAM. Protobuf-lite — специална версия за Android, оптимизирана за размер на генерирания код.
Често задавани въпроси
JSONSerialization — ръчен парсинг, връщащ Any (Dictionary, Array) без типизация. JSONDecoder — автоматична десериализация в Codable типове. JSONSerialization дава гъвкавост за динамични структури, JSONDecoder — скорост и типова безопасност за известни схеми. В production се препоръчва JSONDecoder.
Поточен парсинг е задължителен при отговори от 500 KB, при парсинг на RSS/Atom канали и при анализ на файлове на устройства с ограничена памет. За типични API отговори до 100 KB автоматичната десериализация чрез JSONDecoder или Moshi е за предпочитане — кодът е по-чист и се разработва по-бързо.
Android SDK включва org.json (JSONObject, JSONArray), XmlPullParser (XML) и android.util.JsonReader. За CSV, YAML и Protobuf са необходими допълнителни библиотеки: OpenCSV за CSV, SnakeYAML за YAML, protobuf-javalite за Protobuf.
Използвайте lenient режим в kotlinx.serialization или JsonReader.setLenient(true) в Moshi — прощава излишни запетаи, неекранирани кавички и едноредови коментари. За пълна валидация внедрете контрактно тестване чрез Pact или Spring Cloud Contract.
SAX (Simple API for XML) — поточен XML парсер, генериращ събития startElement, characters, endElement при обхождане на документа. Реализиран чрез XmlPullParser на Android и XMLParser на iOS. Прилага се в RSS четци, синхронизация на офлайн данни и обработка на SVG файлове.
Обобщение
Ще разработим мобилно приложение под ключ
IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.
Прочетете също