tadija / aexml Goto Github PK
View Code? Open in Web Editor NEWSwift minion for simple and lightweight XML parsing
License: MIT License
Swift minion for simple and lightweight XML parsing
License: MIT License
It cramps my style. πΈ It also feels awkward having to type:
let element = elementList["MyElement"]
if element.name != AEXMLElement.errorElementName {
let string = element["MyString"].stringValue
}
as opposed to something like:
let element = elementList["MyElement"]
let string = element["MyString"].stringValue // I would expect string == ""
because 99% of the time I don't want the string, "element <MyString> not found"
, because I use stringValue
. Was under the assumption that stringValue
would return an empty string upon lookup error, not an error string.
This is coming from having used SwiftyJSON. So that is where my expectations are coming from. Feel free to disagree if that's how you feel.
Thoughts?
None of the AEXML objects conform to the NilLiteralConvertible protocol.
Is there a way to access or enumerate attributes that you don't know the name of? I'd like to be able to load all the attributes of an element into a dictionary.
CocoaPods 0.36.0.beta.1 enables support for Swift dependencies.
Are there any plans to support Carthage?
For me it's not possible to perform a carthage update
, an error is thrown:
** BUILD FAILED **
The following build commands failed:
Check dependencies
(1 failure)
A shell task failed with exit code 65:
** BUILD FAILED **
The following build commands failed:
Check dependencies
(1 failure)
A selective build of iOS and Mac only is working fine.
It seems that 1.3.1 is not Swift 2.0-compatible. I fixed the issues (sorry for this pretty unprofessional way of submitting the code, but I'm not used to github...):
snip >>>
//
// AEXML.swift
//
// Copyright (c) 2014 Marko TadiΔ [email protected] http://tadija.net
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
import Foundation
/**
This is base class for holding XML structure.
You can access its structure by using subscript like this: `element["foo"]["bar"]` would return `<bar></bar>` element from `<element><foo><bar></bar></foo></element>` XML as an `AEXMLElement` object.
*/
public class AEXMLElement: Equatable {
// MARK: Properties
/// Every `AEXMLElement` should have its parent element instead of `AEXMLDocument` which parent is `nil`.
public private(set) weak var parent: AEXMLElement?
/// Child XML elements.
public private(set) var children: [AEXMLElement] = [AEXMLElement]()
/// XML Element name.
public let name: String
/// XML Element value.
public var value: String?
/// XML Element attributes.
public private(set) var attributes: [NSObject : AnyObject]
/// String representation of `value` property (if `value` is `nil` this is empty String).
public var stringValue: String { return value ?? String() }
/// Boolean representation of `value` property (if `value` is "true" or 1 this is `True`, otherwise `False`).
public var boolValue: Bool { return stringValue.lowercaseString == "true" || Int(stringValue) == 1 ? true : false }
/// Integer representation of `value` property (this is **0** if `value` can't be represented as Integer).
public var intValue: Int { return Int(stringValue) ?? 0 }
/// Double representation of `value` property (this is **0.00** if `value` can't be represented as Double).
public var doubleValue: Double { return (stringValue as NSString).doubleValue }
// MARK: Lifecycle
/**
Designated initializer - `name` is required, others are optional.
:param: name XML element name.
:param: value XML element value
:param: attributes XML element attributes
:returns: An initialized `AEXMLElement` object.
*/
public init(_ name: String, value: String? = nil, attributes: [NSObject : AnyObject] = [NSObject : AnyObject]()) {
self.name = name
self.value = value
self.attributes = attributes
}
// MARK: XML Read
/// This element name is used when unable to find element.
public class var errorElementName: String { return "AEXMLError" }
// The first element with given name **(AEXMLError element if not exists)**.
public subscript(key: String) -> AEXMLElement {
if name == AEXMLElement.errorElementName {
return self
} else {
let filtered = children.filter { $0.name == key }
return filtered.count > 0 ? filtered.first! : AEXMLElement(AEXMLElement.errorElementName, value: "element <\(key)> not found")
}
}
/// Returns all of the elements with equal name as `self` **(nil if not exists)**.
public var all: [AEXMLElement]? { return parent?.children.filter { $0.name == self.name } }
/// Returns the first element with equal name as `self` **(nil if not exists)**.
public var first: AEXMLElement? { return all?.first }
/// Returns the last element with equal name as `self` **(nil if not exists)**.
public var last: AEXMLElement? { return all?.last }
/// Returns number of all elements with equal name as `self`.
public var count: Int { return all?.count ?? 0 }
/**
Returns all element with given attributes.
:param: attributes Array of Keys (`NSObject`) and Value (`AnyObject`) - both must conform to `Equatable` protocol.
:returns: Optional Array of found XML elements.
*/
public func allWithAttributes <K: NSObject, V: AnyObject where K: Equatable, V: Equatable> (attributes: [K : V]) -> [AEXMLElement]? {
var found = [AEXMLElement]()
if let elements = all {
for element in elements {
var countAttributes = 0
for (key, value) in attributes {
if element.attributes[key] as? V == value {
countAttributes++
}
}
if countAttributes == attributes.count {
found.append(element)
}
}
return found.count > 0 ? found : nil
} else {
return nil
}
}
/**
Counts elements with given attributes.
:param: attributes Array of Keys (`NSObject`) and Value (`AnyObject`) - both must conform to `Equatable` protocol.
:returns: Number of elements.
*/
public func countWithAttributes <K: NSObject, V: AnyObject where K: Equatable, V: Equatable> (attributes: [K : V]) -> Int {
return allWithAttributes(attributes)?.count ?? 0
}
// MARK: XML Write
/**
Adds child XML element to `self`.
:param: child Child XML element to add.
:returns: Child XML element with `self` as `parent`.
*/
public func addChild(child: AEXMLElement) -> AEXMLElement {
child.parent = self
children.append(child)
return child
}
/**
Adds child XML element to `self`.
:param: name Child XML element name.
:param: value Child XML element value.
:param: attributes Child XML element attributes.
:returns: Child XML element with `self` as `parent`.
*/
public func addChild(name name: String, value: String? = nil, attributes: [NSObject : AnyObject] = [NSObject : AnyObject]()) -> AEXMLElement {
let child = AEXMLElement(name, value: value, attributes: attributes)
return addChild(child)
}
/**
Adds given attribute to `self`.
:param: name Attribute name.
:param: value Attribute value.
*/
public func addAttribute(name: NSObject, value: AnyObject) {
attributes[name] = value
}
/**
Adds given attributes to `self`.
:param: attributes Dictionary of Attribute names and values.
*/
public func addAttributes(attributes: [NSObject : AnyObject]) {
for (attributeName, attributeValue) in attributes {
addAttribute(attributeName, value: attributeValue)
}
}
/// Removes `self` from `parent` XML element.
public func removeFromParent() {
parent?.removeChild(self)
}
private func removeChild(child: AEXMLElement) {
if let childIndex = children.indexOf(child) {
children.removeAtIndex(childIndex)
}
}
private var parentsCount: Int {
var count = 0
var element = self
while let parent = element.parent {
count++
element = parent
}
return count
}
private func indentation(count: Int) -> String {
var indent = String()
if count > 0 {
for i in 0..<count {
indent += "\t"
}
}
return indent
}
/// Complete hierarchy of `self` and `children` in **XML** formatted String
public var xmlString: String {
var xml = String()
// open element
xml += indentation(parentsCount - 1)
xml += "<\(name)"
if attributes.count > 0 {
// insert attributes
for (key, value) in attributes {
xml += " \(key)=\"\(value)\""
}
}
if value == nil && children.count == 0 {
// close element
xml += " />"
} else {
if children.count > 0 {
// add children
xml += ">\n"
for child in children {
xml += "\(child.xmlString)\n"
}
// add indentation
xml += indentation(parentsCount - 1)
xml += "</\(name)>"
} else {
// insert string value and close element
xml += ">\(stringValue)</\(name)>"
}
}
return xml
}
/// Same as `xmlString` but without `\n` and `\t` characters
public var xmlStringCompact: String {
let chars = NSCharacterSet(charactersInString: "\n\t")
let parts = xmlString.componentsSeparatedByCharactersInSet(chars)
let result = "".join(parts)
return result
}
}
// MARK: -
/**
This class is inherited from AEXMLElement
and has a few addons to represent XML Document.
XML Parsing is also done with this object.
*/
public class AEXMLDocument: AEXMLElement {
// MARK: Properties
/// This is only used for XML Document header (default value is 1.0).
public let version: Double
/// This is only used for XML Document header (default value is "utf-8").
public let encoding: String
/// This is only used for XML Document header (default value is "no").
public let standalone: String
/// Root (the first child element) element of XML Document **(AEXMLError element if not exists)**.
public var root: AEXMLElement { return children.count == 1 ? children.first! : AEXMLElement(AEXMLElement.errorElementName, value: "XML Document must have root element.") }
// MARK: Lifecycle
/**
Designated initializer - Creates and returns XML Document object.
:param: version Version value for XML Document header (defaults to 1.0).
:param: encoding Encoding value for XML Document header (defaults to "utf-8").
:param: standalone Standalone value for XML Document header (defaults to "no").
:param: root Root XML element for XML Document (defaults to `nil`).
:returns: An initialized XML Document object.
*/
public init(version: Double = 1.0, encoding: String = "utf-8", standalone: String = "no", root: AEXMLElement? = nil) {
// set document properties
self.version = version
self.encoding = encoding
self.standalone = standalone
// init super with default name
super.init("AEXMLDocument")
// document has no parent element
parent = nil
// add root element to document (if any)
if let rootElement = root {
addChild(rootElement)
}
}
/**
Convenience initializer - used for parsing XML data (by calling `readXMLData:` internally).
:param: version Version value for XML Document header (defaults to 1.0).
:param: encoding Encoding value for XML Document header (defaults to "utf-8").
:param: standalone Standalone value for XML Document header (defaults to "no").
:param: xmlData XML data to parse.
:param: error If there is an error reading in the data, upon return contains an `NSError` object that describes the problem.
:returns: An initialized XML Document object containing the parsed data. Returns `nil` if the data could not be parsed.
*/
public convenience init?(version: Double = 1.0, encoding: String = "utf-8", standalone: String = "no", xmlData: NSData, inout error: NSError?) {
self.init(version: version, encoding: encoding, standalone: standalone)
if let parseError = readXMLData(xmlData) {
error = parseError
return nil
}
}
// MARK: Read XML
/**
Creates instance of `AEXMLParser` (private class which is simple wrapper around `NSXMLParser`) and starts parsing the given XML data.
:param: data XML which should be parsed.
:returns: `NSError` if parsing is not successfull, otherwise `nil`.
*/
public func readXMLData(data: NSData) -> NSError? {
children.removeAll(keepCapacity: false)
let xmlParser = AEXMLParser(xmlDocument: self, xmlData: data)
return xmlParser.tryParsing() ?? nil
}
// MARK: Override
/// Override of `xmlString` property of `AEXMLElement` - it just inserts XML Document header at the beginning.
public override var xmlString: String {
var xml = "<?xml version=\"\(version)\" encoding=\"\(encoding)\" standalone=\"\(standalone)\"?>\n"
for child in children {
xml += child.xmlString
}
return xml
}
}
// MARK: -
class AEXMLParser: NSObject, NSXMLParserDelegate {
// MARK: Properties
let xmlDocument: AEXMLDocument
let xmlData: NSData
var currentParent: AEXMLElement?
var currentElement: AEXMLElement?
var currentValue = String()
var parseError: NSError?
// MARK: Lifecycle
init(xmlDocument: AEXMLDocument, xmlData: NSData) {
self.xmlDocument = xmlDocument
self.xmlData = xmlData
currentParent = xmlDocument
super.init()
}
// MARK: XML Parse
func tryParsing() -> NSError? {
var success = false
let parser = NSXMLParser(data: xmlData)
parser.delegate = self
success = parser.parse()
return success ? nil : parseError
}
// MARK: NSXMLParserDelegate
func parser(parser: NSXMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String]) {
currentValue = String()
currentElement = currentParent?.addChild(name: elementName, attributes: attributeDict)
currentParent = currentElement
}
func parser(parser: NSXMLParser, foundCharacters string: String?) {
currentValue += string ?? String()
let newValue = currentValue.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet())
currentElement?.value = newValue == String() ? nil : newValue
}
func parser(parser: NSXMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {
currentParent = currentParent?.parent
currentElement = nil
}
func parser(parser: NSXMLParser, parseErrorOccurred parseError: NSError) {
self.parseError = parseError
}
}
// MARK: - Equatable
/**
Implementation of Equatable
protocol for AEXMLElement
.
*/
public func ==(lhs: AEXMLElement, rhs: AEXMLElement) -> Bool {
if lhs.name != rhs.name { return false }
if lhs.value != rhs.value { return false }
if lhs.parent != rhs.parent { return false }
if lhs.children != rhs.children { return false }
if lhs.attributes != rhs.attributes { return false }
return true
}
/**
Implementation of Equatable
protocol for AEXMLElement
.
*/
public func !=(lhs: [NSObject: AnyObject], rhs: [NSObject: AnyObject]) -> Bool {
for (key, lhsValue) in lhs {
if let rhsValue: AnyObject = rhs[key] {
if !(lhsValue === rhsValue) { return true }
} else { return true }
}
return false
}
<<<
I notice the lack of a remove child feature. Are there any plans for this to incorporated in the future? Or some mostly simply way of doing it (like set an element to nil or something)?
Thanks!
In the old version everything worked fine but now I have this problem:
XML Document must have root element.
AEXML.swift:119:42: '?' must be followed by a call, member lookup, or subscript
private var parentsCount: Int {
var count = 0
var element = self
while let parent = element.parent? {
count++
element = parent
}
return count
}
Is there a way to pass a variable extract the following? or maybe there's another simple way of doing this.
var theColor = "yellow"
xmlDoc.root["cats"]["cat"].allWithAttributes(["breed" : "Domestic", "color" : "(theColor)"])
or
xmlDoc.root["cats"]["cat"].allWithAttributes(["breed" : "Domestic", "color" : theColor"])
var theInt = 44
xmlDoc.root["event"]["date"].allWithAttributes(["event" : theInt]))
xmlDoc.root["event"]["date"].countWithAttributes(["event" : theInt]))
Without any changes, after downloading latest code, 3 unit tests fail:
testChildrenElements()
testAllElements()
testLastElement()
I was actually trying to debug an issue with Xcode 6.3 Beta, but then I realized that I could not get the tests to run without crashing. However, I had to make 1 change to get code to compile, so I thought maybe my change caused the failure.
However, then I went back to Xcode 6.1.1 and am seeing these 3 test failures.
Will submit separate issue for the Xcode 6.3 beta.
Looks like a very nice library, but I would prefer using a library which utilizes unit tests. In case of an XML parses this could have been in done in little number of lines of code (for example).
Unit tests doesn't only ensure that code works as expected, they are also a good reference for new users of a framework.
I'm not sure if this is somehow a problem with AEXML or a bug in XCode, or some other weird thing, so pardon me if it has nothing to do with this library.
Somehow, I'm getting an error on a file that doesn't use AEXML that there is a cast from AEXMLElement. If I comment out the #import AEXML
line (in a totally unrelated file) then the project builds. Then when I uncomment the import, it builds fine.
I put together a simple sample project to illustrate this.
line 223 of AEXML.swift has:
if let parser = NSXMLParser(data: xmlData) {
Though, it appears as of the most recent Xcode, the following is required:
if let parser = NSXMLParser(data: xmlData) as NSXMLParser! {
Can you please validate my change is correct, and why you are not seeing this issue.
Thanks,
Brian
--delete this (found my issue)--
let dataString1 = "<?xml version='1.0' encoding='utf-8'?><results><error>No entry for today</error></results>"
let dataString2 = "<?xml version='1.0' encoding='utf-8'?><results><entry>Some entry</entry></results>"
let data = dataString1.dataUsingEncoding(NSUTF8StringEncoding)
var xmlError: NSError?
if let xmlDoc = AEXMLDocument(xmlData: data!, error: &xmlError) {
let errorTag = xmlDoc.root["error"]
// always going to be true
if xmlDoc.root["error"].name == "error" {
let e = NSError(domain: "...", code: 101, userInfo: [NSLocalizedDescriptionKey: errorTag.stringValue])
return onFailure(error: e)
}
// never gets to here...
}
When dataString1 is used, the code above behaves as expected. <error>
tag is determined as "error" and handled as such.
When dataString2 is used, the above fails to find <error>
tag in the data and the check omits element "error" not found
"error".
There seems to be no way to distinguish between actual <error>
tag and missing <error>
tag unless I just make an exception for stringValue == element <error> not found
.
I think that existence of <error>
should not be handled inside AEXML. Or at least not be the same kind of error as is when xmlDoc.root["error"].name
returns "error".
Checking for existence of <error>
tag should be with a != instead of ==.
Should allow you to do xmlDoc.root["error"].name != "error"
instead of the current xmlDoc.root["error"].name == "error"
.
Hi, Before upgrading to latest version of xcode 6.3.1. AEXML was working perfectly. But after upgrade it is crashing. below is the error message.
Optional("XML Document must have root element.")
nil
fatal error: Array index out of range
please fix this issue as soon as possible because my project depends on this.
Thanks & Regards
Sayeed.
Could you please help me in parsing this format.
I am not able to correctly parse this kind of format: I want to get the 'text' attributes value of all prop given 'child' index value.
For ex: get all prop's 'text' value given 'child' index 1
root
child index="1" name="child name 1"
prop index="1" text="prop name1" /
prop index="2" text="prop name2" /
/child
child index="2" name="child name 2"
prop index="1" text="prop name1" /
prop index="2" text="prop name2" /
/child
/root
Hi,
I did tweet you on twitter.
According to AEXML, I would like to ask that is it possible to parse different level of xml given by attribute name and attribute value. The problem is there is many different level structures and not the same to every file I want to use.
For example,
Example1.xml
level1
id="01"
id="02"
....level2
....id="03"
....
id="04" (this is in level 1)
Example2.xml
level1
id="01"
..level2
..id="02"
.....level3
.......id="03"
..........
..
Another problem is I would like to get those value in order which will contain many value in the block to the same array structure. It looks weird format, I actually got my own solution by checking every case but sometimes I still miss some case. But I'm not sure if it is better way.
Sorry for my bad English.
Hope this is not confusing you. Thank you so much.
I was tracking a memory leak in an app that I am writing that uses AEXML and finally traced the leak to AEXMLElement. The thing is that once you add children to an AEXMLElement, it does not get deinitialized, even if set to nil.
To reproduce I added a deinit "function" to AEXMLElement, AEXMLDocument and AEXMLParser like
deinit {
NSLog("Deinit AEXMLElement")
}
Then I ran the following code in an app. The code does not work in PlayGrounds since there is an issue with deinits in PlayGround: http://stackoverflow.com/questions/24021340/memory-leaks-in-the-swift-playground-deinit-not-called-consistently
var a: AEXMLDocument?
var b: AEXMLDocument?
a = AEXMLDocument(version: 1.0, encoding: "UTF8")
b = AEXMLDocument(version: 1.0, encoding: "UTF8")
a!.addChild("child", value: "value")
println("- a -")
a = nil
println("- b -")
b = nil
println("-----")
When you run the code, you will see something like
- a -
- b -
2014-11-23 17:12:52.654 x-x[12068:1088859] Deinit AEXMLDocument
2014-11-23 17:12:52.655 x-x[12068:1088859] Deinit AEXMLElement
-----
in the console. This shows that only b is deinitialized.
Without digging too far into your code I assume that there is one or more circular reference between a parent element and their children.
I get the following error:
AEXML-1.3.1/AEXMLExample/ViewController.swift:27:38: Cannot invoke initializer for type 'AEXMLDocument' with an argument list of type '(xmlData: NSData, error: inout NSError?)'
Any suggestions to what may be the issue?
Let's modify the first cat on example.xml
test file as follow:
<cat breed="Siberian" color="lightgray" value="99">Tinna</cat>
The attribute value
is added.
Now add the following test to testAttributes()
unit test:
XCTAssertEqual(firstCatAttributes["value"] as Int, 99, "Should be able to return INT attribute value.")
A crash then occur: EXC_BAD_ACCESS
While adding this attribute using addAttribute
and then reading i, it works fine:
var firstCat = exampleXML.root["cats"]["cat"]
firstCat.addAttribute("value", value: 99)
XCTAssertEqual(firstCat.attributes["value"] as Int, 99, "Should be able to return INT attribute value")
Using Xcode 7.3 with target deployment set to iOS 9.3 (using pods) I'm seeing the error:
Module file was created by an older version of the compiler; rebuild 'AEXML' and try again...
Are there any plans to address this incompatibility with the latest version of the compiler please?
An Xml like the following one will result in wrong Value for the Element version:
<Document><version>1.0</version>\n\t</Document>
Current Implementation produces for the Element with Name version value "1.0\n\t" which is wrong.
Expected Value should be "1.0"
Current implementation should be changed to:
func parser(parser: NSXMLParser!, didEndElement elementName: String!, namespaceURI: String!, qualifiedName qName: String!) {
currentParent = currentParent?.parent
currentValue = String()
currentElement = nil
}
Building archive fails. Modification must be done to the project settings:
Carthage/Carthage#535
Following up with previous feature request, would it be possible to prepend a Child element? I'm currently using my string replacement method to do this.
I know prepending a Child is a rarely used feature, but I would greatly appreciate it.
Thanks again,
atn
__
Update
__
Ended up changing some of my code around, so you can skip on doing this if you want since it would be so rarely used.
Please add a CHANGELOG.md file to make it easier to see what changes with each version. It also gets imported into the CocoaPods directory.
I know it may not be appropriate to note issues found using Xcode beta, but I thought I would submit this anyway.
The code compiles after a couple minor changes. But it crashes when running the tests.
After some debugging, it looks like this is related to the issue described here:
For Swift 1.2, it also looks like the NSXMLParserDelegate function declarations have changed slightly, which may also have been causing the delegate functions to be called.
I discovered some weird behavior of allWithAttributes: it returns nil.
I tested it with following code:
let xmlDoc = try AEXMLDocument(xmlData: result.dataUsingEncoding(NSUTF8StringEncoding)!)
let root = xmlDoc.root
print(root.children[0].attributes)
let xxx = xmlDoc.root.allWithAttributes(["id": "0"])
print(xxx)
And this prints:
["id": "0"]
nil
My xml looks like this:
<gpio>
<rgb id="0">
<manually>false</manually>
<led id="red">true</led>
<led id="blue">true</led>
<led id="green">true</led>
<interactible>true</interactible>
</rgb>
<rgb id="1">
<manually>false</manually>
<led id="red">true</led>
<led id="blue">true</led>
<led id="green">true</led>
<interactible>true</interactible>
</rgb>
</gpio>
Do I miss something or is this a misbehavior of allWithAttributes?
Thanks,
Chromo
Cocoapod complains that AEXML requires iOS 8.0 but the requirement on README said iOS 7.0+.
It seems that AEXML's xmlstring property does not escape characters like "greater than", "less than" and "ampersand". This in turn leads to invalid XML being returned if an element's value contains such a character. Alternatively escaping could also be done when adding an element. Nor sure which is the better way...
Hi,
I want to delete element from xml. and i am trying to delete using below code but it throws runtime error "EXC_BAD_ACCESS"
auditElement.removeFromParent()
What could be the issue ?
Please suggest.
Thanks.
I'm submitting a new bug related to #66. I responded to your response, but I didn't see anything after that.
Below is my response:
Sorry, I missed escaping opening the in the previous comment.
Below is the XML that is valid and AEXML was not correctly taking in.
SAMPSON Aside to GREGORY Is the law of our side, if I say ay?Nearly all methods (including subscriptions and constructors) are not public. Without declaring them as public it is impossible to use that class when using it within an framework.
What should I do if I want to read xml string?
thanks :P
I'm getting a really strange issue where the compiler is throwing a warning that a previous NSDictionary object is being automatically converted to an AEXMLElement. If I remove AEXML my code compiles fine. The model code in my screenshot below is not using AEXML at all. I've never seen this issue before and I'm wondering if this is a Swift 2.0 XCode 7.0 bug or something.
When receiving an XML (for example from a web service) I would prefer to check if the response applies to the defined XSD schema before trying to process it. At the moment there aren't any Swift XML frameworks available which support XSD validation at the moment. Would be a great feature.
First, very cool work. Love the simple and super-easy API. Great job!
Perhaps I've not yet appreciated the finer points of Swift, but I'm wondering if the subscript, and last functions/properties can return nilable AEXMLElement (i.e. AEXMLElement?) ?
For my use case, I don't know if a server's XML response will have certain elements. I want to access them if they are present.
Right now, it appears when I do something like this:
let errorDetail = xmlDocument!.rootElement["errorDetail"]
...I get a dummy empty AEXMLElement, but I really just want nil in this case.
Again, thanks for the great work!
Hi !
I wonder if there is a way to bind the data with xml.
I mean, create a model class then bind the data by using a xml file.
I know that it's possible on Android, but i'm new to IOS :/
It's possible ?
Or if you have an other way to do it, because my models are complex and I can't bind the data by me self.
I am using an old version, but I think this is still in the source - if you set an attribute value to a string with an & in it, it is written unescaped by .xmlString
Hi,
I found a memory leak in the computed property xmlString. A pull request was already submitted.
All the best,
Thorsten
Hi Team,
Good Day!
Am familiar in XML Parsing using NSXMLParser in Objective-C. Now, am working in Swift I can use the NSXMLParser to parse the XML Response but, I have got suggestions to use third party framework (Library) to parse the xml content easily. I googled and found "AEXML" framework for SWIFT programming. I got confused to access the tags from "AEXMLElement".
I have attached the sample response and my sample code for your reference.
I want to parse the main tag "item" and its sub tags "title", "link", "description", "author", "pubDate". How can I handle this?
Can you please help me to parse the xml files like this?
Looking forward your help. Thank you.
Warm Regards,
Yuvaraj M
Can I create an array struct for all child element with a specific value? Need to choose
cats->cat->name: Tinna
the problem is my xml file has no any breeds, need to check values.
It would be nice to be able to use all
in a way like that:
for element in parent.all {
}
This will work already, but if there are zero elements, it should get called with self
. So I wondered why all
isn't nil-able already. Returning self
of course makes sense for many functions of this library, I understand, but I don't see any sense in returning self
in all too.
I also noticed that there is a small inconsistence about it in the library: AEXMLElement.allWithAttributes
is nil-able, while AEXMLElement.all
is not.
I'm parsing some Shakespeare xml files with AEXML (which is working great for me otherwise BTW) when I experience some problems getting the correct values out of elements from the following xml:
SAMPSON Aside to GREGORY Is the law of our side, if I say ay?I'm running through the SPEECH element (speechElement:AEXMLElement)
for child in speechElement.children {
// when child equals the the first LINE element
child.value // should equal "Is the law of our side, if I say" but is nil
}
The LINE element contains the STAGEDIR element correctly, but loses anything after the STAGEDIR.
I've also moved the STAGEDIR element in the line, like so:
Is the law of Aside to GREGORY our side, if I say
and " our side, if I say" is lost.
I've worked around it by modifying the xml files, but I wanted to file a bug and let you know.
I'm trying to add a new element to an xml doc like so:
if let document = AEXMLDocument(xmlData: data, error: &error) {
let attributes = ["location": fishData.location]
let fish = document["FISHDICT"].addChild(name: "FISH", attributes: attributes)
But this overwrites the last element in the document. Am I doing something wrong?
How to parse xml like this
<users>
<user>
<name>
<age>
</user>
</users>
i tried
for user in xmlDoc.root["users"]["user"].all! {
for child in user.children{
switch(child.name){
case "name":
break
case "age":
break
default:
break
}
}
}
but i dont know if this is the best way to do it.
Currently, there is no way to set the XMLParser shouldProcessNamespaces to true. So when accessing an element, the complete tagname with namespace needs to be passed. e.g xml["f:animal"] instead of just xml["animal"]
for example in my xml
var x = anelement["attrib"]["attrib"]
returns an AEXMLElement with a good parent
var x = someelements["attrib"]["attrib"].all!
returns some AEXMLElements but each with parent=nil
that cost me a lot of hours today π
A declarative, efficient, and flexible JavaScript library for building user interfaces.
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. πππ
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google β€οΈ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.