How to parse each column of a table separately using kanna - swift

I just started learning parsing and tried swiftsoup earlier, but I couldn't correctly parse each column separately
my url https://menu.sttec.yar.ru/timetable/rasp_first.html
Now I switched to kanna and am trying to do parsing through .xpath, but I don't have any print output, what am I doing wrong?
my code
var tempArray = [String]()
let urlString = URL(string: "https://menu.sttec.yar.ru/timetable/rasp_first.html")
if let myURL = try? HTML(url: urlString!, encoding: String.Encoding.utf8) {
for item in myURL.css("tr") {
tempArray.append(item["td"]!)
print(tempArray)
}

Related

How to edit and update xml file with Swift

I'm trying to merge two xml files to a new xml file. Also adding one line <xxxxxxxxxxXML Seperatorxxxxxxxxxx> in between two xml.
I'm using SWXMLHash pod to parser my xml file. I already have two var of xml that I need to merge. Thanks!
var oldXML: XMLIndexer?
var newXML: XMLIndexer?
var combinedXML: XMLIndexer?
func mergeEHR(oldXML: XMLIndexer, newXML: XMLIndexer) -> XMLIndexer {
do {
/// Don't know how to merge it.
} catch {
print(error)
}
}
I want it to be
var combinedXML =
<oldXML>
...
</oldXML>
xxxxxxxxxxXML Seperatorxxxxxxxxxx
<newXML>
...
</newXML>
Since combined XML will be not a valid XML (even if it was, doesn't matter), treat them as a raw String:
let oldXMLString = try! String(contentsOfFile: <#PathToOldXML#>) // If it is on the file, else assign it the way it should
let separator = "<xxxxxxxxxxXML Seperatorxxxxxxxxxx>"
let newXMLString = try! String(contentsOfFile: <#PathToNewXML#>) // If it is on the file, else assign it the way it should
let combinedXMLString = [oldXMLString, separator, newXMLString].joined(separator: "\n")
try! combinedXMLString.write(toFile: <#PathToDestinationOfTheCombinedXML#>, atomically: <#Bool#>, encoding: <#String.Encoding#>)
Then you can treat the result as an invalid XML or etc. again.

Reading URLS in JSON api with swift

For work we have a third party company which supply a JSON api for some functionality. The JSON contains urls which I try to map in my code with URL(string: ...) but this fails on some urls which have spaces.
For example:
var str = "https://google.com/article/test test.html"
let url = URL(string: str) //nil
Should I ask the third party to encode their URLs ?
Is this normal or should I try to add encoding myself?
Encoding myself is hard I think because the path should be encoded different from the query and the host shouldn't be encoded etc.
Or am I overthinking this?
If the URL contains spaces in its path, escape the characters with addingPercentEncoding(withAllowedCharacters passing the urlPathAllowed character set:
let str = "https://google.com/article/test test.html"
if let escapedString = str.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlPathAllowed),
let url = URL(string:escapedString) {
print(url)
} else {
print("url \(str) could not be encoded")
}
What I would do if I were you, is to split the string up on the space, try converting each of the elements to a url, and when that works save it in your variable.
var str = "https://google.com/article/test test.html"
var url: URL? = nil
for urlString in str.components(separatedBy: .whitespacesAndNewlines) {
let url = URL(string: urlString)
if url != nil {
break
}
}
// url might be nil here, so test for value before using it
If each URL that you get from the API is in the format in your example, you can instead just grab the first element after spitting the string.
var str = "https://google.com/article/test test.html"
if let urlString = str.components(separatedBy: .whitespacesAndNewlines).first {
let url = URL(string: urlString)
}
// url might be nil here, so test for value before using it

Getting mySql data from url in swift 3 - again

I have asked this seemingly very simple and straight forward question a few times now, never got a solution.
I have a url to obtain mySql data
// 1. get url
let url = URL(string:"http://www.mobwebplanet.com/phpWebService/sample.php")
// 2. Fetch data from url
let data = try? Data(contentsOf: url!)
//playground Output is: 102 bytes. So obviously xcode gets the response data from the URL.
Then I move on to extracting the data:
//3. Create a dictionary from data:
let urlDict = try? JSONSerialization.jsonObject(with: data!, options: [])
// playground Output is: [["Latitude": "37.331741", "Address": "1 Infinite Loop Cupertino, CA", "Name": "Apple", "Longitude": "-122"]]
print(urlDict!)
// playground Output is: "(\n {\n Address = "1 Infinite Loop Cupertino, CA";\n Latitude = "37.331741";\n Longitude = "-122";\n Name = Apple;\n }\n)\n"
My understanding is urlDict is of a Any type. Am I correct?
My biggest question is how can I (cast or convet) urlDict so that I can access the value using key=>value? Like this:
urlDict!["Address"] Outputs "1 Infinite Loop Cupertino, CA"
urlDict!["Latitude"] Outputs "37.331741"...
I am a newbie to Swift so I am doing this as an exercise, any help will be greatly appreciated.
Your JSON response returns an Array of Dictionary objects. So you just need to cast correctly.
let urlString = "http://www.mobwebplanet.com/phpWebService/sample.php"
let url = URL(string: urlString)!
let data = try? Data(contentsOf: url)
if let json = try? JSONSerialization.jsonObject(with: data!, options: []) as? [[String:Any]] {
for location in json! {
print(location["Longitude"])
print(location["Latitude"])
print(location["Address"])
}
}
Output:
Optional(-122)
Optional(37.331741)
Optional(1 Infinite Loop Cupertino, CA)

How do I convert a file into a JSON Object in SwiftyJson

I am trying to import Json data from a user uploaded txt file into a standard object that I can use via SwiftyJson framework
Here is the contents of the text fie:
{
"String": "answer",
"String2": "answer2"
}
I have successfully read it and turned it into a String file using:
let openPanel = NSOpenPanel()
let arrayOfExtensions = ["txt"]
openPanel.allowedFileTypes = arrayOfExtensions
let result = openPanel.runModal()
if result == NSFileHandlingPanelCancelButton {
return
}
let fileUrl = openPanel.URL
do {
let stringResult = try String(contentsOfURL: fileUrl!, encoding: NSUTF8StringEncoding)
print (stringResult)
completionhandler(retrievedData: stringResult, error: nil)
I am trying to convert this into a JSON object using:
let jsonFile = JSON(contentsOfFile)
The problem is that the resulting JSON object created appears to be blank for all the fields except rawvalue.
Here is the screenshot from the debug console.
How to I sucessfully read in the string from the file and then make it populate via SwiftJson correctly?
The problem above was that I was using the wrong method to parse it into JSON.
SwiftyJSON seems to be badly documented hence others had a similar problem.
The correct way to do this is to use :
let jsonFile = JSON.parse(string:contentsOfFile)

Is it ok to use tid-kijyun Swift-HTML-Parser to parse a real world html file from webpage

So the thing is, I am new to programming, and Swift in particular. I completed some courses and now want to build something really simple: an app that gets the news from website and pushes it to a Table View.
Right now I am stuck on error:
Optional(Error Domain=HTMLParserdomain Code=1 "The operation couldn’t be completed. (HTMLParserdomain error 1.)")
The code I wrote is really simple. It's the example from the tid-kijyun repo plus some code to get content of the HTML (func perFormConnectionToGrabUrlContent)
func perFormConnectionToGrabUrlContent(# url: String) -> NSString {
let url = NSURL(string: url)
let request = NSURLRequest(URL: url!)
var htmlContentTemp: NSString = ""
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue()) {
(response, data, error) in
htmlContentTemp = NSString(data: data, encoding: NSUTF8StringEncoding)!
println(htmlContentTemp)
}
return htmlContentTemp
}
let html = perFormConnectionToGrabUrlContent(url: "http://www.google.com")
println(html)
var err: NSError?
var parser = HTMLParser(html: html, error: &err)
if err != nil {
println(err)
exit(1)
}
var bodyNode = parser.body
if let inputNodes = bodyNode?.findChildTags("a") {
for node in inputNodes {
println(node.contents)
}
}
if let inputNodes = bodyNode?.findChildTags("a") {
for node in inputNodes {
println(node.contents)
println(node.getAttributeNamed("href"))
}
}
So the question still is, should I change something in code and it should really work like a charm, or should I better go access the database of website I am trying to reach and run some datebase queries or something like that instead?