Swift minion for simple and lightweight XML parsing
I made this for personal use, but feel free to use it or contribute. For more examples check out Sources and Tests.
This is not a robust full featured XML parser, but rather simple, lightweight and easy to use utility for casual XML handling.
- Read XML data
- Write XML string
- Covered with unit tests
- Covered with inline docs
Let's say this is some XML string you picked up somewhere and made a variable data: Data from that.
<?xml version="1.0" encoding="utf-8"?>
<animals>
<cats>
<catbreed="Siberian"color="lightgray">Tinna</cat>
<catbreed="Domestic"color="darkgray">Rose</cat>
<catbreed="Domestic"color="yellow">Caesar</cat>
<cat></cat>
</cats>
<dogs>
<dogbreed="Bull Terrier"color="white">Villy</dog>
<dogbreed="Bull Terrier"color="white">Spot</dog>
<dogbreed="Golden Retriever"color="yellow">Betty</dog>
<dogbreed="Miniature Schnauzer"color="black">Kika</dog>
</dogs>
</animals>This is how you can use AEXML for working with this data:
(for even more examples, look at the unit tests code included in project)
guardletlet xmlPath = Bundle.main.path(forResource:"example", ofType:"xml"),let data =try?Data(contentsOf:URL(fileURLWithPath: xmlPath))else{return}do{letxmlDoc=tryAEXMLDocument(xml: data, options: options)
// prints the same XML structure as original
print(xmlDoc.xml)
// prints cats, dogs
forchildin xmlDoc.root.children {print(child.name)}
// prints Optional("Tinna") (first element)
print(xmlDoc.root["cats"]["cat"].value)
// prints Tinna (first element)
print(xmlDoc.root["cats"]["cat"].string)
// prints Optional("Kika") (last element)
print(xmlDoc.root["dogs"]["dog"].last?.value)
// prints Betty (3rd element)
print(xmlDoc.root["dogs"].children[2].string)
// prints Tinna, Rose, Caesar
iflet cats = xmlDoc.root["cats"]["cat"].all {forcatin cats {iflet name = cat.value {print(name)}}}
// prints Villy, Spot
fordogin xmlDoc.root["dogs"]["dog"].all! {iflet color = dog.attributes["color"]{if color =="white"{print(dog.string)}}}
// prints Tinna
iflet cats = xmlDoc.root["cats"]["cat"].all(withValue:"Tinna"){forcatin cats {print(cat.string)}}
// prints Caesar
iflet cats = xmlDoc.root["cats"]["cat"].all(withAttributes:["breed":"Domestic","color":"yellow"]){forcatin cats {print(cat.string)}}
// prints 4
print(xmlDoc.root["cats"]["cat"].count)
// prints Siberian
print(xmlDoc.root["cats"]["cat"].attributes["breed"]!)
// prints <cat breed="Siberian" color="lightgray">Tinna</cat>
print(xmlDoc.root["cats"]["cat"].xmlCompact)
// prints Optional(AEXML.AEXMLError.elementNotFound)
print(xmlDoc["NotExistingElement"].error)}catch{print("\(error)")}Let's say this is some SOAP XML request you need to generate.
Well, you could just build ordinary string for that?
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelopexmlns:xsd="http://www.w3.org/2001/XMLSchema"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soap:Header>
<m:Transxmlns:m="http://www.w3schools.com/transaction/"soap:mustUnderstand="1">234</m:Trans>
</soap:Header>
<soap:Body>
<m:GetStockPrice>
<m:StockName>AAPL</m:StockName>
</m:GetStockPrice>
</soap:Body>
</soap:Envelope>Yes, but, you can also do it in a more structured and elegant way with AEXML:
// create XML Document
letsoapRequest=AEXMLDocument()letattributes=["xmlns:xsi":"http://www.w3.org/2001/XMLSchema-instance","xmlns:xsd":"http://www.w3.org/2001/XMLSchema"]letenvelope= soapRequest.addChild(name:"soap:Envelope", attributes: attributes)letheader= envelope.addChild(name:"soap:Header")letbody= envelope.addChild(name:"soap:Body")
header.addChild(name:"m:Trans", value:"234", attributes:["xmlns:m":"http://www.w3schools.com/transaction/","soap:mustUnderstand":"1"])letgetStockPrice= body.addChild(name:"m:GetStockPrice")
getStockPrice.addChild(name:"m:StockName", value:"AAPL")
// prints the same XML structure as original
print(soapRequest.xml).Package(url: "https://github.com/tadija/AEXML.git", majorVersion: 4)github "tadija/AEXML"pod'AEXML'
AEXML is released under the MIT license. See LICENSE for details.