提问人:Daniel Fernandez 提问时间:4/23/2021 最后编辑:Daniel Fernandez 更新时间:4/24/2021 访问量:518
在 swift 中解析同名的 XML 子标签
Parse XML subtags with same name in swift
问:
我是 Swift 的新手。我创建了一个 XML 解析器,可以逐个读取每个标签(标签和子标签)。我发现的问题是有一些同名的子标签,所以我的代码无法区分。我需要知道如何读取具体的子标签以区分并将其存储在不同的变量中。
这是我正在解析的 XML(简化):
<_0:situationRecord id="GUID_Suc_3971318_3971318" xsi:type="_0:NetworkManagement">
<_0:identifier>171826</_0:identifier>
<_0:to xsi:type="_0:TPEGNonJunctionPoint">
<_0:name>
<_0:descriptor>
<_0:value>MADRID</_0:value>
</_0:descriptor>
<_0:tpegDescriptorType>other</_0:tpegDescriptorType>
</_0:name>
</_0:to>
<_0:from xsi:type="_0:TPEGNonJunctionPoint">
<_0:name>
<_0:descriptor>
<_0:value>SANTIAGO DE COMPOSTELA</_0:value>
</_0:descriptor>
<_0:tpegDescriptorType>other</_0:tpegDescriptorType>
</_0:name>
</_0:from>
</_0:situationRecord>
这是我的ParseINCDGT.swift类:
import Foundation
struct INCIDENCIADGT {
var identifier: String
var valueFrom: String
var valueTo: String
}
class ParseINCDGT: NSObject, XMLParserDelegate {
private var myData: Data
private var currentElementName = ""
private var inItem = false
private var item: INCIDENCIADGT
var ready = false
var auxLat = 1
var auxLong = 1
var aux = 1
var items: [INCIDENCIADGT]
override init() {
//Default values
myData = "".data(using: .ascii)!
items = []
item = INCIDENCIADGT(identifier: "", valueFrom: "", valueTo: "")
}
// Set the local data set for parsing
func setData(data: Data) -> Void {
if data == nil {
return
}
myData = data
}
// Runs the parsing process, returns at the end. Please note that this function is synchronous, while internally asynchronous
func parse() -> Void {
let parser = XMLParser(data: myData)
parser.delegate = self
parser.parse()
}
// Terminate session
func parserDidEndDocument(_ parser: XMLParser) {
ready = true
}
// Start session
func parserDidStartDocument(_ parser: XMLParser) {
ready = false
}
// Terminate an element
func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {
currentElementName = elementName
if elementName == "_0:situationRecord" {
inItem = false
items.append(item)
}
}
// Starts an element
func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String] = [:]) {
currentElementName = elementName
if elementName == "_0:situationRecord" {
inItem = true
item = INCIDENCIADGT(identifier: "", valueFrom: "", valueTo: "")
}
}
// Collects other data
func parser(_ parser: XMLParser, foundCharacters string: String) {
switch currentElementName{
case "_0:identifier":
item.identifier += string.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)
case "_0:value":
item.valueFrom += string.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)
default:
break
}
}
}
这是我调用ParserINCDGT.swift的方法:
func loadData() -> Void {
let url = "http://infocar.dgt.es/datex2/dgt/SituationPublication/all/content.xml"
let request = URLRequest(url: URL(string: url)!)
let session3 = URLSession.shared.dataTask(with: request3) {
(data, _, error) in
//Handle errors
if error != nil {
//Show error message
return
}
guard let data = data else{
//Data error, show message
return
}
//Convert data to string
var s: String = String(data: data, encoding: .ascii)!
//Make XML conforming to all standards: Convert LF to CR
s = s.replacingOccurrences(of: "\r", with: "\n")
//Parse XML
let p = ParseINCDGT()
p.setData(data: data)
p.parse()
//Elaborate data
print(p.items)
if (p.items.count != 0) {
for item in p.items {
print(item.identifier)
print(item.valueFrom)
}
}
}
//Run!
session.resume()
}
最后,变量“valueForm”的输出是“MADRIDSANTIAGO DE COMPOSTELA”
谁能帮我解释一下我应该包含什么来解析和区分子标签“_0:value”?
非常感谢。任何帮助都是值得赞赏的。
答:
1赞
Jelumar
4/24/2021
#1
您只需要添加一些更改:
检查标签是否已启动并将其保存在变量中,我在这里调用了它,您需要将其添加到您的类中(private 会更好)。当您在其中查找文本时,请将其添加到 INCIDENCIADGT 结构的正确元素中。_0:from
_0:to
isFrom
_0:value
Herer,您会看到两个需要更改的功能,需要添加的内容:
// Starts an element
func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String] = [:]) {
currentElementName = elementName
if elementName == "_0:situationRecord" {
inItem = true
item = INCIDENCIADGT(identifier: "", valueFrom: "", valueTo: "")
} else if elementName == "_0:from" { // check if we will be looking at from information when getting the next _0:value
isFrom = true // could use an enum if more posibilities exist than from and to.
} else if elementName == "_0:to" { // check if getting to information like above
isFrom = false // could use an enum if more posibilities exist than from and to.
}
}
// Collects other data
func parser(_ parser: XMLParser, foundCharacters string: String) {
switch currentElementName{
case "_0:identifier":
item.identifier += string.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)
case "_0:value":
if isFrom { // write the information in the right field of the struct
item.valueFrom += string.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)
} else {
item.valueTo += string.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)
}
default:
break
}
}
我写的内容可能仍然存在一些错误和警告,因为我只是在编辑器中制作了它,并没有在 xcode 中对其进行测试,但如果它不起作用,它至少让您了解如何开始解决您的特定问题。
评论
1赞
Daniel Fernandez
4/27/2021
非常感谢您的回复。在周末将它调整为我的代码后,它运行良好。
下一个:从 XML 内容解析图像
评论