Я работаю над проектом, который обрабатывает ответы xml. После поиска я нашел библиотеку на github drmohundro / SWXMLHash , которая работает на основе Swifty JSON. Через некоторое время я понял, что не могу получить значения с экранированием.
Ответ xml выглядит как
let xmlResponseString = "<TrackList><Entry><Id>2</Id><Uri>/Input/E21u</Uri><Metadata><DIDL-Lite xmlns="urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:upnp="urn:schemas-upnp-org:metadata-1-0/upnp/"><item id="E21"><dc:title>Doing It To Death</dc:title><upnp:album>Ash & Ice</upnp:album><upnp:artist>The Kills</upnp:artist><upnp:class>object.item.audioItem.musicTrack</upnp:class><upnp:albumArtURI>http://192.168.1.106:8088/storage/emulated/0/record_cache/album_art/1535461905688.jpg</upnp:albumArtURI><res sampleFrequency="96000" bitsPerSample="24" bitrate="2304000" nrAudioChannels="2" protocolInfo="http-get:*:audio/mpeg" duration="00:04:07.431">/Input/E21</res></item></DIDL-Lite></Metadata></Entry></TrackList>"
В ответе название альбома равно "Ash & Ice". Однако возвращаемое значение равно «Ясень»
Вот так я получаю значение:
let xmlHash = SWXMLHash.parse(xmlResponseString)
albumName = xmlHash["DIDL-Lite"]["item"]["upnp:album"].element?.text
Кроме того, проверка «xmlHash» выглядит так, как будто ошибка уже произошла из «SWXMLHash.parse (xmlResponseString)».
Нужно ли экранировать xmlResponseString?
Это то, что библиотека не обрабатывает должным образом?
Любая альтернатива?
Спасибо
EDIT
Ответ приходит от другого устройства поставщика OpenHome.
Оригинальный ответ:
<TrackList>
<Entry>
<Id>2</Id>
<Uri>/Input/E21u</Uri>
<Metadata><DIDL-Lite xmlns="urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:upnp="urn:schemas-upnp-org:metadata-1-0/upnp/"><item id="E21"><dc:title>Doing It To Death</dc:title><upnp:album>Ash & Ice</upnp:album><upnp:artist>The Kills</upnp:artist><upnp:class>object.item.audioItem.musicTrack</upnp:class><upnp:albumArtURI>http://192.168.1.106:8088/storage/emulated/0/record_cache/album_art/1535461905688.jpg</upnp:albumArtURI><res sampleFrequency="96000" bitsPerSample="24" bitrate="2304000" nrAudioChannels="2" protocolInfo="http-get:*:audio/mpeg" duration="00:04:07.431">/Input/E21</res></item></DIDL-Lite>
</Metadata>
</Entry>
По словам разработчика, значение метаданных было экранировано, потому что это XML внутри XML. Не уверен, если это имеет значение
Поскольку я хочу создать универсальную функцию разбора для заполнения класса, я создал этот метод:
func unescapeXMLPredefinedCharacters(value:String?) -> String{
var audioString = ""
if value != nil{
audioString = value!
//Replace Unicode HTML Entity
audioString = audioString.replacingOccurrences(of: """, with: "\"")
audioString = audioString.replacingOccurrences(of: "&", with: "&")
audioString = audioString.replacingOccurrences(of: "'", with: "'")
audioString = audioString.replacingOccurrences(of: "<", with: "<")
audioString = audioString.replacingOccurrences(of: ">", with: ">")
//Replace Unicode Decimal
audioString = audioString.replacingOccurrences(of: """, with: "\"")
audioString = audioString.replacingOccurrences(of: "&", with: "&")
audioString = audioString.replacingOccurrences(of: "'", with: "'")
audioString = audioString.replacingOccurrences(of: "<", with: "<")
audioString = audioString.replacingOccurrences(of: ">", with: ">")
//Replace Unicode Hex
audioString = audioString.replacingOccurrences(of: """, with: "\"")
audioString = audioString.replacingOccurrences(of: "&", with: "&")
audioString = audioString.replacingOccurrences(of: "'", with: "'")
audioString = audioString.replacingOccurrences(of: "<", with: "<")
audioString = audioString.replacingOccurrences(of: ">", with: ">")
}
return audioString
}
Он не знает, какой тип юникода использовался для эскапинга.
Тогда я получаю ответ от моего первоначального вопроса