0

我正在处理一个处理 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>&#60;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/"&#62;&#60;item id="E21"&#62;&#60;dc:title&#62;Doing It To Death&#60;/dc:title&#62;&#60;upnp:album&#62;Ash &#38; Ice&#60;/upnp:album&#62;&#60;upnp:artist&#62;The Kills&#60;/upnp:artist&#62;&#60;upnp:class&#62;object.item.audioItem.musicTrack&#60;/upnp:class&#62;&#60;upnp:albumArtURI&#62;http://192.168.1.106:8088/storage/emulated/0/record_cache/album_art/1535461905688.jpg&#60;/upnp:albumArtURI&#62;&#60;res sampleFrequency="96000" bitsPerSample="24" bitrate="2304000" nrAudioChannels="2" protocolInfo="http-get:*:audio/mpeg" duration="00:04:07.431"&#62;/Input/E21&#60;/res&#62;&#60;/item&#62;&#60;/DIDL-Lite&#62;
    </Metadata>
</Entry>

根据开发人员的说法,Metadata 值已被转义,因为它是 XML 中的 XML。不确定这是否重要

因为我想创建一个通用解析函数来填充一个类,所以我创建了这个方法:

func unescapeXMLPredefinedCharacters(value:String?) -> String{

var audioString = ""

if value != nil{

    audioString = value!

    //Replace Unicode HTML Entity
    audioString = audioString.replacingOccurrences(of: "&quot;", with: "\"")
    audioString = audioString.replacingOccurrences(of: "&amp;", with: "&")
    audioString = audioString.replacingOccurrences(of: "&apos;", with: "'")
    audioString = audioString.replacingOccurrences(of: "&lt;", with: "<")
    audioString = audioString.replacingOccurrences(of: "&gt;", with: ">")


    //Replace Unicode Decimal
    audioString = audioString.replacingOccurrences(of: "&#34;", with: "\"")

    audioString = audioString.replacingOccurrences(of: "&#38;", with: "&")
    audioString = audioString.replacingOccurrences(of: "&#39;", with: "'")
    audioString = audioString.replacingOccurrences(of: "&#60;", with: "<")
    audioString = audioString.replacingOccurrences(of: "&#62;", with: ">")


    //Replace Unicode Hex
    audioString = audioString.replacingOccurrences(of: "&#x22;", with: "\"")
    audioString = audioString.replacingOccurrences(of: "&#x26;", with: "&")
    audioString = audioString.replacingOccurrences(of: "&#x27;", with: "'")
    audioString = audioString.replacingOccurrences(of: "&#x3c;", with: "<")
    audioString = audioString.replacingOccurrences(of: "&#x3e;", with: ">")

}

return audioString

}

它不知道哪种 unicode 类型已用于转义。

然后我从我原来的问题中得到答案

4

2 回答 2

1

问题是转义的内部 xml 在某种意义上已经是错误的,因为它包含&字符(在 unicode 中),也许<还有其他。

首先,您不应该转义 unicode 实体,例如或根本不转义,因为 XmlParser 会为您处理这些。&amp;&lt;

然后,您应该将诸如等之类的 unicode 实体转义为诸如(而不是 to )之类的&#38;xml 实体,然后 xml 解析器将处理这些实体(见上文)&amp;&

于 2018-08-29T12:34:42.807 回答
0

根据安德烈亚斯回答,我改变了功能

func unescapeXMLPredefinedCharacters(value:String?) -> String{

    var audioString = ""

    if value != nil{

        audioString = value!

        //Replace Unicode Decimal
        audioString = audioString.replacingOccurrences(of: "&#34;", with: "&quot;")
        audioString = audioString.replacingOccurrences(of: "&#38;", with: "&amp;")
        audioString = audioString.replacingOccurrences(of: "&#39;", with: "&apos;")
        audioString = audioString.replacingOccurrences(of: "&#60;", with: "&lt;")
        audioString = audioString.replacingOccurrences(of: "&#62;", with: "&gt;")

    }

    return audioString

}
于 2018-08-29T15:25:39.533 回答