草庐IT

json - 如何在swift 3中转换xml和json数据

coder 2023-09-10 原文

我是 IOS 新手,我想使用 swift 3 将从 SOAP Web 服务接收的一些混合数据(xml 和 JSON 混合数据)转换为数组。 我在解析器方法中的字符串变量中接收此数据。

func connection(_ connection: NSURLConnection, didFailWithError error: Error){
    print("\(error)")
    print("Some error in your Connection. Please try again.")
    let alert = UIAlertController(title: "Error", message: "No internet connection", preferredStyle: UIAlertControllerStyle.alert)

    // add an action (button)
    alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: nil))

    self.present(alert, animated: true, completion: nil)
}

func connectionDidFinishLoading(_ connection: NSURLConnection){

    print("Received \(UInt(webResponseData.count)) Bytes")
    // let theXML = String(webResponseData.mutableBytes, length: webResponseData.length, encoding: String.Encoding.utf8)
    let theXML =  XMLParser(data: webResponseData)
    theXML.delegate = self
    theXML.parse()
    print("\(theXML)")
}

func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String, qualifiedName qName: String, attributes attributeDict: [AnyHashable: Any]){
    currentElement = elementName
   // print(currentElement)
}

func parser(_ parser: XMLParser, foundCharacters string: String){

   currentElement = string
    UserDefaults.standard.set(currentElement, forKey: "string")

    //print(currentElement)
   // arr.append(currentElement)
}

func parser(_ parser: XMLParser,didEndElement elementName: String, namespaceURI: String?,qualifiedName qName: String?){

    let sessionelement = UserDefaults.standard.object(forKey: "string")
    print(sessionelement!)
}

这是来自网络服务的响应:

[{"Id":2,"imgName":"_U11tmp1464839741959976567.jpg","SeqNo":1},
{"Id":1,"imgName":"_U11tmp1464839741959976567.jpg","SeqNo":2},
{"Id":3,"imgName":"_U11tmpIMG-14117-WA59976567.jpg","SeqNo":3}]

最佳答案

借助以下代码块,您可以将任何复杂的 XML 转换为 JSON。我正在转换 50 页的 XML,它的效果很好。一旦你得到 json,你可以直接将它映射到你的模型类。

import Foundation
class ParseXMLData: NSObject, XMLParserDelegate {

var parser: XMLParser
var elementArr = [String]()
var arrayElementArr = [String]()
var str = "{"

init(xml: String) {
    parser = XMLParser(data: xml.replaceAnd().replaceAposWithApos().data(using: String.Encoding.utf8)!)
    super.init()
    parser.delegate = self
}

func parseXML() -> String {
    parser.parse()

    // Do all below steps serially otherwise it may lead to wrong result
    for i in self.elementArr{
        if str.contains("\(i)@},\"\(i)\":"){
            if !self.arrayElementArr.contains(i){
                self.arrayElementArr.append(i)
            }
        }
        str = str.replacingOccurrences(of: "\(i)@},\"\(i)\":", with: "},") //"\(element)@},\"\(element)\":"
    }

    for i in self.arrayElementArr{
        str = str.replacingOccurrences(of: "\"\(i)\":", with: "\"\(i)\":[") //"\"\(arrayElement)\":}"
    }

    for i in self.arrayElementArr{
        str = str.replacingOccurrences(of: "\(i)@}", with: "\(i)@}]") //"\(arrayElement)@}"
    }

    for i in self.elementArr{
        str = str.replacingOccurrences(of: "\(i)@", with: "") //"\(element)@"
    }

    // For most complex xml (You can ommit this step for simple xml data)
    self.str = self.str.removeNewLine()
    self.str = self.str.replacingOccurrences(of: ":[\\s]?\"[\\s]+?\"#", with: ":{", options: .regularExpression, range: nil)

    return self.str.replacingOccurrences(of: "\\", with: "").appending("}")
}

// MARK: XML Parser Delegate
func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String]) {

    //print("\n Start elementName: ",elementName)

    if !self.elementArr.contains(elementName){
        self.elementArr.append(elementName)
    }

    if self.str.last == "\""{
        self.str = "\(self.str),"
    }

    if self.str.last == "}"{
        self.str = "\(self.str),"
    }

    self.str = "\(self.str)\"\(elementName)\":{"

    var attributeCount = attributeDict.count
    for (k,v) in attributeDict{
        //print("key: ",k,"value: ",v)
        attributeCount = attributeCount - 1
        let comma = attributeCount > 0 ? "," : ""
        self.str = "\(self.str)\"_\(k)\":\"\(v)\"\(comma)" // add _ for key to differentiate with attribute key type
    }
}

func parser(_ parser: XMLParser, foundCharacters string: String) {
    if self.str.last == "{"{
        self.str.removeLast()
        self.str = "\(self.str)\"\(string)\"#" // insert pattern # to detect found characters added
    }
}

func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {

    //print("\n End elementName \n",elementName)
    if self.str.last == "#"{ // Detect pattern #
        self.str.removeLast()
    }else{
        self.str = "\(self.str)\(elementName)@}"
    }
}
}

添加字符串扩展

extension String{
    // remove amp; from string
func removeAMPSemicolon() -> String{
    return replacingOccurrences(of: "amp;", with: "")
}

// replace "&" with "And" from string
func replaceAnd() -> String{
    return replacingOccurrences(of: "&", with: "And")
}

// replace "\n" with "" from string
func removeNewLine() -> String{
    return replacingOccurrences(of: "\n", with: "")
}

func replaceAposWithApos() -> String{
    return replacingOccurrences(of: "Andapos;", with: "'")
}
}

从类(class)打电话

let xmlStr = "<Your XML string>"
let parser = ParseXMLData(xml: xmlStr)
let jsonStr = parser.parseXML()
print(jsonStr)

希望对您有所帮助。

关于json - 如何在swift 3中转换xml和json数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45609447/

有关json - 如何在swift 3中转换xml和json数据的更多相关文章

  1. ruby - 如何在 Ruby 中顺序创建 PI - 2

    出于纯粹的兴趣,我很好奇如何按顺序创建PI,而不是在过程结果之后生成数字,而是让数字在过程本身生成时显示。如果是这种情况,那么数字可以自行产生,我可以对以前看到的数字实现垃圾收集,从而创建一个无限系列。结果只是在Pi系列之后每秒生成一个数字。这是我通过互联网筛选的结果:这是流行的计算机友好算法,类机器算法:defarccot(x,unity)xpow=unity/xn=1sign=1sum=0loopdoterm=xpow/nbreakifterm==0sum+=sign*(xpow/n)xpow/=x*xn+=2sign=-signendsumenddefcalc_pi(digits

  2. ruby - 如何在 buildr 项目中使用 Ruby 代码? - 2

    如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby​​

  3. ruby - 什么是填充的 Base64 编码字符串以及如何在 ruby​​ 中生成它们? - 2

    我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%

  4. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  5. ruby-on-rails - 如何从 format.xml 中删除 <hash></hash> - 2

    我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为

  6. ruby - 如何使用文字标量样式在 YAML 中转储字符串? - 2

    我有一大串格式化数据(例如JSON),我想使用Psychinruby​​同时保留格式转储到YAML。基本上,我希望JSON使用literalstyle出现在YAML中:---json:|{"page":1,"results":["item","another"],"total_pages":0}但是,当我使用YAML.dump时,它不使用文字样式。我得到这样的东西:---json:!"{\n\"page\":1,\n\"results\":[\n\"item\",\"another\"\n],\n\"total_pages\":0\n}\n"我如何告诉Psych以想要的样式转储标量?解

  7. ruby-on-rails - 如何在 ruby​​ 中使用两个参数异步运行 exe? - 2

    exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby​​中使用两个参数异步运行exe吗?我已经尝试过ruby​​命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何ruby​​gems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除

  8. ruby - 如何在续集中重新加载表模式? - 2

    鉴于我有以下迁移:Sequel.migrationdoupdoalter_table:usersdoadd_column:is_admin,:default=>falseend#SequelrunsaDESCRIBEtablestatement,whenthemodelisloaded.#Atthispoint,itdoesnotknowthatusershaveais_adminflag.#Soitfails.@user=User.find(:email=>"admin@fancy-startup.example")@user.is_admin=true@user.save!ende

  9. ruby-on-rails - Rails HTML 请求渲染 JSON - 2

    在我的Controller中,我通过以下方式在我的index方法中支持HTML和JSON:respond_todo|format|format.htmlformat.json{renderjson:@user}end在浏览器中拉起它时,它会自然地以HTML呈现。但是,当我对/user资源进行内容类型为application/json的curl调用时(因为它是索引方法),我仍然将HTML作为响应。如何获取JSON作为响应?我还需要说明什么? 最佳答案 您应该将.json附加到请求的url,提供的格式在routes.rb的路径中定义。这

  10. ruby - 如何在 Ruby 中拆分参数字符串 Bash 样式? - 2

    我正在为一个项目制作一个简单的shell,我希望像在Bash中一样解析参数字符串。foobar"helloworld"fooz应该变成:["foo","bar","helloworld","fooz"]等等。到目前为止,我一直在使用CSV::parse_line,将列分隔符设置为""和.compact输出。问题是我现在必须选择是要支持单引号还是双引号。CSV不支持超过一个分隔符。Python有一个名为shlex的模块:>>>shlex.split("Test'helloworld'foo")['Test','helloworld','foo']>>>shlex.split('Test"

随机推荐