tadija/AEXML
tadija/AEXML has 1,036 GitHub stars and 202 forks. GitHot measured +1 in 7 days. Last checked 2026-11-11 02:14 UTC. Last push 2026-10-15.
Swift minion for simple and lightweight XML parsing
What you can do
- Write XML string
- Covered with unit tests
- Covered with inline docs
Measured star growth
- in 24h
- Update delayed
- in 7 days
- +1
- in 15 days
- Collecting history
- in 1 month
- Collecting history
Net star changes over overlapping periods, not daily totals. Missing measurements are left blank. Stars measure attention, not software quality.
README.md
OriginalAEXML
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.
Index
Intro
This is not a robust full featured XML parser, but rather simple, lightweight and easy to use utility for casual XML handling.
Features
- Read XML data
- Write XML string
- Covered with unit tests
- Covered with inline docs
Usage
Read XML
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>
<cat breed="Siberian" color="lightgray">Tinna</cat>
<cat breed="Domestic" color="darkgray">Rose</cat>
<cat breed="Domestic" color="yellow">Caesar</cat>
<cat></cat>
</cats>
<dogs>
<dog breed="Bull Terrier" color="white">Villy</dog>
<dog breed="Bull Terrier" color="white">Spot</dog>
<dog breed="Golden Retriever" color="yellow">Betty</dog>
<dog breed="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)
guard let
let xmlPath = Bundle.main.path(forResource: "example", ofType: "xml"),
let data = try? Data(contentsOf: URL(fileURLWithPath: xmlPath))
else { return }
do {
let xmlDoc = try AEXMLDocument(xml: data, options: options)
// prints the same XML structure as original
print(xmlDoc.xml)
// prints cats, dogs
for child in 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
if let cats = xmlDoc.root["cats"]["cat"].all {
for cat in cats {
if let name = cat.value {
print(name)
}
}
}
// prints Villy, Spot
for dog in xmlDoc.root["dogs"]["dog"].all! {
if let color = dog.attributes["color"] {
if color == "white" {
print(dog.string)
}
}
}
// prints Tinna
if let cats = xmlDoc.root["cats"]["cat"].all(withValue: "Tinna") {
for cat in cats {
print(cat.string)
}
}
// prints Caesar
if let cats = xmlDoc.root["cats"]["cat"].all(withAttributes: ["breed" : "Domestic", "color" : "yellow"]) {
for cat in 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)")
}
Write XML
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:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soap:Header>
<m:Trans xmlns: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
let soapRequest = AEXMLDocument()
let attributes = ["xmlns:xsi" : "http://www.w3.org/2001/XMLSchema-instance", "xmlns:xsd" : "http://www.w3.org/2001/XMLSchema"]
let envelope = soapRequest.addChild(name: "soap:Envelope", attributes: attributes)
let header = envelope.addChild(name: "soap:Header")
let body = envelope.addChild(name: "soap:Body")
header.addChild(name: "m:Trans", value: "234", attributes: ["xmlns:m" : "http://www.w3schools.com/transaction/", "soap:mustUnderstand" : "1"])
let getStockPrice = body.addChild(name: "m:GetStockPrice")
getStockPrice.addChild(name: "m:StockName", value: "AAPL")
// prints the same XML structure as original
print(soapRequest.xml)
Or perhaps like this, using result builders (see #186):
@AEXMLDocumentBuilder
private func buildSoapEnvelope(
for action: String,
in serviceType: String,
with parameters: [String: String] = [:]
) -> AEXMLDocument {
AEXMLElement("s:Envelope", attributes: [
"xmlns:s": "http://schemas.xmlsoap.org/soap/envelope/",
"s:encodingStyle": "http://schemas.xmlsoap.org/soap/encoding/"
]) {
AEXMLElement("s:Body") {
AEXMLElement("s:\(action)", attributes: [
"xmlns:u": serviceType
]) {
for parameter in parameters {
AEXMLElement(
name: parameter.key,
value: parameter.value
)
}
}
}
}
}
Installation
-
.package(url: "https://github.com/tadija/AEXML.git", from: "4.7.3") -
github "tadija/AEXML" -
pod 'AEXML'
License
AEXML is released under the MIT license. See LICENSE for details.
Explore related projects
codecrafters-io/build-your-own-x
Master programming by recreating your favorite technologies from scratch.
561,634 starspublic-apis/public-apis
A collective list of free APIs
497,996 starsmorluto/rea
Reverse engineer anything with agents, from app behavior down to native binaries.
450,341 starsopenclaw/openclaw
The AI that really does things. Any OS. Any Platform. The lobster way. 🦞
394,308 stars