xcode 如何在 OSX 上的 Swift 6.1 中解析 XML 字符串?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26581240/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 06:00:53  来源:igfitidea点击:

How to parse an XML string in Swift 6.1 on OSX?

xcodemacosswiftxcode6

提问by TERACytE

I'm new to Swift and I'm trying to create an OSX terminal app to parse an xml file. I've got it reading the file in to a string, but cannot figure out how parse it in to a structure I can then navigate and pull data from. It appears that NSXMLDocument seems to want a URL and NSXMLParser needs a delegate, but my initial attempts could not get them to work.

我是 Swift 的新手,我正在尝试创建一个 OSX 终端应用程序来解析一个 xml 文件。我已经将文件读入字符串,但无法弄清楚如何将其解析为结构,然后我可以导航并从中提取数据。看起来 NSXMLDocument 似乎想要一个 URL,而 NSXMLParser 需要一个委托,但我最初的尝试无法让它们工作。

Here's what I've got so far:

这是我到目前为止所得到的:

import Foundation
import Cocoa

let path = "//Users/<path>/someFile.xml"

var err: NSError?
let content = String.stringWithContentsOfFile(path, encoding: NSUTF8StringEncoding, error: &err)

The structure of the xml file is something like this:

xml文件的结构是这样的:

<?xml version="1.0" encoding="UTF-8"?>
<Data>
  <Documents>
    <List>
      <Document name="name1" type="TYPE1" date="some string">
        <Items>
          <Item name="item1" dataType="DATATYPE1" version="1">
          <Item name="item2" dataType="DATATYPE9" version="4">
        </Items>
      </Document>
      <Document name="name2" type="TYPE4" date="some string">
      ...
    </List>
  </Documents>
</Data>

Your help is much appreciated.

非常感谢您的帮助。

回答by zisoft

Parsing an XML document is not that trivial and cannot be done with a one-liner in code.

解析一个 XML 文档并不是那么简单,而且不能用一行代码来完成。

To parse it with NSXMLParseryou need a custom class that implements the NSXMLParserDelegateprotocol, like this:

要解析它,NSXMLParser您需要一个实现NSXMLParserDelegate协议的自定义类,如下所示:

class myXMLParser: NSObject, NSXMLParserDelegate {
    ...

    func parseFile(filename: String) {
        let url = NSBundle.mainBundle().URLForResource(filename, withExtension: "xml")

        if let parser = NSXMLParser(contentsOfURL: url) {
            parser.delegate = self
            parser.parse()
        }
    }   


    func parserDidStartDocument(parser: NSXMLParser!) {
        ...
    }

    func parserDidEndDocument(parser: NSXMLParser!) {
        ...
    }

    func parser(parser: NSXMLParser!, didStartElement elementName: String!, namespaceURI: String!, qualifiedName qName: String!, attributes attributeDict: [NSObject : AnyObject]!) {
        ...
    }

    func parser(parser: NSXMLParser!, foundCharacters string: String!) {
        ...
    }

    func parser(parser: NSXMLParser!, didEndElement elementName: String!, namespaceURI: String!, qualifiedName qName: String!) {
        ...
    }

}

So whenever you retrieve a new element with didStartElementyou have to check what element it is and what child elements you expect further. This all depends on the structure of your XML document so there is no all in one solution one can give you.

因此,每当您检索一个新元素时,didStartElement您都必须检查它是什么元素以及您期望进一步的子元素。这一切都取决于您的 XML 文档的结构,因此无法为您提供多合一的解决方案。

回答by rkusa

The NSXMLDocumentusage would look like:

NSXMLDocument使用将如下所示:

let fm = NSFileManager.defaultManager()
var err : NSError?
let userDirectory = fm.URLForDirectory(.UserDirectory, inDomain: .UserDomainMask, appropriateForURL: nil, create: false, error: &err)
if err != nil {
  // ...
}

if let path = userDirectory?.URLByAppendingPathComponent("someFile.xml") {
  NSXMLDocument(contentsOfURL: configURL, options: 0, error: &err)
  if err != nil {
    // ...
  }

  if let rootNode = config?.rootElement() {
    // ...
  }
}