在 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 class:
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”?
非常感谢。感谢任何帮助。
您只需添加一些更改:
检查标签_0:from
或_0:to
是否启动并保存在变量中,我这里叫它isFrom
,你需要把它添加到你的class(私人会更好)。当您在 _0:value
中查找文本时,您将其添加到 INCIDENCIADGT 结构的正确元素中。
在这里您可以看到需要更改的两个函数以及需要添加的内容:
// 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中测试它,但如果它不起作用,它至少给出了你知道如何开始解决你的具体问题。
我是 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 class:
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”?
非常感谢。感谢任何帮助。
您只需添加一些更改:
检查标签_0:from
或_0:to
是否启动并保存在变量中,我这里叫它isFrom
,你需要把它添加到你的class(私人会更好)。当您在 _0:value
中查找文本时,您将其添加到 INCIDENCIADGT 结构的正确元素中。
在这里您可以看到需要更改的两个函数以及需要添加的内容:
// 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中测试它,但如果它不起作用,它至少给出了你知道如何开始解决你的具体问题。