Analyse der XML-Datei in Swift (Xcode v 7.0.1) und abrufen von Werten aus dem Wörterbuch
Ich versuche zu analysieren, eine XML-Datei im Swift-und ich bin mit ein wenig Schwierigkeiten zu verstehen, wie die NSMutableDictionary Werke in die Speicherung der Werte von Elementen.
Die XML-Datei sieht wie folgt aus,
<coord2 count="6">
<markers>
<marker>
<lat>36.99058167</lat>
<lng>-122.06620333</lng>
<timestamp>1444931620</timestamp>
<route>LOOP</route>
<id>7855</id>
<predictions>
,4,5,,6,7,,,,10,,,11,,11,,13,15,,14,,,16,,,0,,,2,,,,,,,,,,,,,,
</predictions>
<update_seconds>10</update_seconds>
<index>4</index>
</marker>
<marker>
<lat>36.99296</lat>
<lng>-122.06517333</lng>
<timestamp>1444934786</timestamp>
<route>UPPER CAMPUS</route>
<id>7860</id>
<predictions>
15,,,14,,,13,12,11,,10,9,,8,,7,,,6,,5,4,,3,2,,1,0,,,,,,,,,,,,,,,
</predictions>
<update_seconds>10</update_seconds>
<index>4</index>
</marker>
</markers>
<curr_time>1444931622</curr_time>
</coord2>
Den Weg versuche ich zu analysieren, wird die XML-Datei mit dem folgenden code den ich gefunden habe aus einem tutorial an
http://www.theappguruz.com/blog/xml-parsing-using-nsxmlparse-swift
import UIKit
import GoogleMaps
class ViewController: UIViewController, NSXMLParserDelegate {
var parser = NSXMLParser()
var posts = NSMutableArray()
var elements = NSMutableDictionary()
var element = NSString()
var route = NSMutableString()
var timestamp = NSMutableString()
func beginParsing()
{
posts = []
parser = NSXMLParser(contentsOfURL:(NSURL(string:"http://xmfile.xml"))!)!
parser.delegate = self
parser.parse()
}
override func viewDidLoad() {
super.viewDidLoad()
beginParsing()
print("The route is")
let t = elements["route"]!
print(t)
print("The timestamp is")
let u = elements["timestamp"]!
print(u)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
//Dispose of any resources that can be recreated.
}
//didStartElement
func parser(parser: NSXMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String])
{
element = elementName
if (elementName as NSString).isEqualToString("marker")
{
elements = NSMutableDictionary()
elements = [:]
route = NSMutableString()
route = ""
timestamp = NSMutableString()
timestamp = ""
}
}
//foundCharacters
func parser(parser: NSXMLParser, foundCharacters string: String)
{
if element.isEqualToString("route") {
route.appendString(string)
} else if element.isEqualToString("timestamp") {
timestamp.appendString(string)
}
}
//didEndElement
func parser(parser: NSXMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?)
{
if (elementName as NSString).isEqualToString("marker") {
if !route.isEqual(nil) {
elements.setObject(route, forKey: "route")
}
if !timestamp.isEqual(nil) {
elements.setObject(timestamp, forKey: "timestamp")
}
posts.addObject(elements)
}
}
}
Momentan bin ich nur mit Schwerpunkt auf der "route" - und "timestamp" - Elemente einfach, ein Verständnis zu gewinnen, wie die Analyse funktioniert. Die Ausgabe die ich bekomme, wenn ich
let t = elements["route"]!
print(t)
print("previous is route")
let u = elements["timestamp"]!
print(u)
print("previous is timestamp")
ist immer der Wert der letzten Elemente, die diese Namen in der XML-Datei. So, für die Beispiel-XML-Datei sofern ich die Ausgabe für die 6 Zeilen code oben würde
Die route ist
OBEREN CAMPUS
Der timestamp ist
1444934786
Ich möchte in der Lage sein, zu unterscheiden zwischen mehreren "marker" Elemente in der XML-Datei und rufen Sie die Werte der Elemente innerhalb der Markierung. In anderen Worten, in der Lage sein, um die Werte der Elemente innerhalb der ersten Markierung auch nicht gerade der Letzte. Wie würde ich gehen über das tun dies?
- Sie benötigen zur Nutzung NSMutableDictionary / NSMutableArray oder wäre die Schaffung von Klassen zur Darstellung von Coord2 / Marker-eine option? Grund warum ich Frage ist, dass, wenn Sie können benutzerdefinierte Klassen, die Sie verwenden können, ein anderer Ansatz sauber zu analysieren, XML, und haben mehr überschaubaren code...
- Danke für die Antwort. Jetzt bin ich offen für Vorschläge. Ich bin ziemlich neu in Swift, damit ich Lerne wie ich gehen. Wie würde ich dies bewerkstelligen mit custom classes?
- Okay... ich habe eine Antwort für Sie; bitte überprüfen Sie es heraus unten.
Du musst angemeldet sein, um einen Kommentar abzugeben.
HINWEIS
Ich habe die ganze Sache im Kern, die Sie kopieren und einfügen können in einen Spielplatz.
Schauen wir uns ein einfaches Beispiel zum Einstieg:
Etwas eingeengt, aber der Marker kann ein Objektname (string) und lat-Wert (int). Ein Coord2 wird ein array von Markierungen, und ein count (int) attribute.
Analysieren, die oben mit benutzerdefinierten Klassen, hier ist ein Ansatz.
Erstellen Sie zuerst eine ParserBase Klasse, dass einige Boden-Arbeit für uns, nämlich die Anhäufung foundCharacters, so dass es leicht verwendet werden können, die durch sub-Klassen.
Auch (noch wichtiger) es hat eine
parent
Eigenschaft, die verwendet wird, um Verweise auf die übergeordnete container-Klasse [das ist für die Art und Weise, in der wir uns Parsen von XML].Seit coord2 ist unsere Wurzel-tag, erstellen wir eine Klasse, die eine Zuordnung zu diesem tag - es repräsentiert das root-Objekt, hat eine Reihe von Markern, die eine count-Eigenschaft, und ist auch die Wurzel delegate-Objekt für den XMLParser.
Den Marker-Klasse ist wie folgt:
Nun zu analysieren, extrahieren von Informationen, und drucken etwas.
welche Ausgänge die folgende:
override func viewDidLoad() { .. }
Funktion?viewDidLoad
... Wie für die URL, wie waren Sie mit der Zusammenarbeit der parser so weit? Wenn Sie gebaut hatte, es mit etwas wieparser = NSXMLParser(contentsOfURL:(NSURL(string:"http://xmfile.xml"))!)!
mögen, dann verwenden Sie, dass an die Stelle der entsprechenden Zeile im letzten block. (Ich war mit einem Spielplatz, so musste die XML in einen string.)var lat = ""
,var lati = 0.0
,self.lat = foundCharacters
,self.lati = (self.lat as NSString).doubleValue
. Der Wert vonself.lat
ist "36.97728" aberself.lati
bleiben 0.0let s = "34.223"; let doubleValue = Double(s) ?? 0 // try to make a double else its 0
foundCharacters
ist etwas um die Zeichenfolge "36.97728". Wenn ichvar lat = ""; self.lat = foundCharacters; let doubleFromlat = Double(self.lat)
,doubleFormat
zugewiesen bekommtnil
. Ich habe gelesen, dass dies passiert, wenn die Zeichenfolge, die Sie versuchen zu casten als Verdoppeln können nicht gewirkt werden. Zum BeispielDouble("abc")
wirdnil
.self.lat = foundCharacters; print(self.lat)
bekomme ich die Ausgabe: ** 36.97728** (also 4 Leerzeichen gedruckt vor "36.97728" zusammen mit einem neue-Zeile rechts oben) Könnte dies das Problem verursachen?coord.markers
- und array? Wie unterscheide ich die verschiedenenmarkers
innerhalb der XML-Datei? Kann ich tuncoord.marker[0]
,coord.marker[1]
,coord.marker[2]
usw.? DANKE.Benutzt habe ich die Klasse Erstellt, die unten Zu bekommen Wörterbuch Von XML-Daten.
https://github.com/Bhaavik/BDXmlParser
Müssen Sie die Klasse und rufen Sie einfach Unter der Funktion für die Wörterbuch-Reaktion
lassen objXmlParser = BbXmlParser()
lassen Sie dictResponse = objXmlParser.getdictionaryFromXmlData(Daten!)
print(dictResponse)
Und hier gehen Sie mit dem Wörterbuch. 🙂
Swift 2.2:
Davon aus, dass deine xml-Datei wird sich in einem beliebigen, wo in Ihrem pc und lassen Sie die xml-Datei ist :
Also, wenn Sie wollen, Lesen Sie nur die Testfälle Namen aus dieser xml,verwenden Sie den folgenden code:
Rufen Sie jetzt die Funktion wie:
wenn
aufgerufen wird, wird als parser-Funktion aufgerufen wird, und führen Sie den erforderlichen job.Die Ausgabe ist:
Eine weitere wichtige Sache ist-parser überladene Funktion. Sie können Sie als Ihre Anforderung.
Zum Beispiel, wenn Sie brauchen, um zu Lesen
aus der xml-Datei, verwenden Sie die unten parser-Funktion in der XmlParsing Klasse:
Dies ist der link zu finden, api details:https://developer.apple.com/library/ios/documentation/Cocoa/Reference/NSXMLParserDelegate_Protocol/#//apple_ref/occ/intfm/NSXMLParserDelegate/parser:foundComment: