drmohundro/SWXMLHash 和 Swift 中的转义值
drmohundro/SWXMLHash and escaping values in Swift
我正在处理一个处理 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"。但是返回的值是 "Ash "
这就是我获取值的方式:
let xmlHash = SWXMLHash.parse(xmlResponseString)
albumName = xmlHash["DIDL-Lite"]["item"]["upnp:album"].element?.text
此外,检查 "xmlHash" 看起来错误已经来自 "SWXMLHash.parse(xmlResponseString)"。
"xmlResponseString" 是否需要转义?
这是图书馆没有正确处理的事情吗?
还有其他选择吗?
谢谢
编辑
响应来自另一个 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。不确定这是否重要
因为我想创建一个通用的解析函数来填充 class,所以我创建了这个方法:
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
}
它不知道使用了哪种 unicode 类型进行反转义。
然后我从我原来的问题中得到答案
问题是 escaped 内部 xml 在某种意义上已经是错误的,它包含 &
个字符(在 unicode 中),也许 <
和其他人。
首先,您应该不 unescape unicode 实体,例如&
或<
,因为XmlParser 会为您处理。
然后,您应该将 &
等 unicode 实体转义为 xml 实体,例如 &
(而不是 &
),然后 xml 解析器将处理(见上文)
根据Andreas Answer,我改变了函数
func unescapeXMLPredefinedCharacters(value:String?) -> String{
var audioString = ""
if value != nil{
audioString = value!
//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: ">")
}
return audioString
}
我正在处理一个处理 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"。但是返回的值是 "Ash "
这就是我获取值的方式:
let xmlHash = SWXMLHash.parse(xmlResponseString)
albumName = xmlHash["DIDL-Lite"]["item"]["upnp:album"].element?.text
此外,检查 "xmlHash" 看起来错误已经来自 "SWXMLHash.parse(xmlResponseString)"。
"xmlResponseString" 是否需要转义? 这是图书馆没有正确处理的事情吗? 还有其他选择吗?
谢谢
编辑 响应来自另一个 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。不确定这是否重要
因为我想创建一个通用的解析函数来填充 class,所以我创建了这个方法:
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
}
它不知道使用了哪种 unicode 类型进行反转义。
然后我从我原来的问题中得到答案
问题是 escaped 内部 xml 在某种意义上已经是错误的,它包含 &
个字符(在 unicode 中),也许 <
和其他人。
首先,您应该不 unescape unicode 实体,例如&
或<
,因为XmlParser 会为您处理。
然后,您应该将 &
等 unicode 实体转义为 xml 实体,例如 &
(而不是 &
),然后 xml 解析器将处理(见上文)
根据Andreas Answer,我改变了函数
func unescapeXMLPredefinedCharacters(value:String?) -> String{
var audioString = ""
if value != nil{
audioString = value!
//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: ">")
}
return audioString
}