HTMLSAXParser is a lightweight, synchronous SAX-style HTML parser for Swift 6. It wraps the HTMLParser API from libxml2 and reports parsing events through a closure.
The package supports macOS 10.15, iOS 13, tvOS 13, watchOS 6, and visionOS 1 or later. Apple supplies libxml2 in these platforms' SDKs, so you don't need to install another dependency or configure header search paths.
Add HTMLSAXParser to your package dependencies:
dependencies: [
.package(
url: "https://github.com/raymccrae/swift-htmlsaxparser.git",
from: "1.0.0"
)
]Then add the library to your target:
.target(
name: "YourTarget",
dependencies: ["HTMLSAXParser"]
)Create a parser and handle the events you need:
import HTMLSAXParser
let parser = HTMLSAXParser()
try parser.parse(string: "<p>Hello, world!</p>") { context, event in
switch event {
case let .startElement(name, attributes):
print("Start: \(name), attributes: \(attributes)")
case let .characters(text):
print("Text at line \(context.location.line): \(text)")
case let .endElement(name):
print("End: \(name)")
default:
break
}
}Use parse(data:encoding:handler:) when the HTML is stored as Data. If you omit encoding, libxml2 attempts to detect it.
The handler runs synchronously on the calling thread. Call context.abortParsing() from the handler to stop normally without receiving more events. Don't store the context or use it outside the handler invocation.
HTMLSAXParser is Sendable, and you can use one instance for concurrent parse operations. Each operation has an independent libxml2 parser context and SAX handler.
Pass a ParseOptions value when you create the parser:
let parser = HTMLSAXParser(parseOptions: [
.recover,
.noNetwork,
.noImpliedElements
])The default options recover from malformed HTML, remove blank nodes, prevent network access, suppress implied elements, and compact text nodes.
The package also provides entity-encoding helpers for UTF-8 strings and data:
let encoded = #"<a title="Example">"#.encodeHTMLEntities()
// <a title="Example">
let singleQuoted = "'Example'".encodeHTMLEntities(
quoteCharacter: .singleQuote
)
// 'Example'The Data overload returns nil for invalid UTF-8 or input that exceeds libxml2's supported length.
Version 1.0 is a major update with these compatibility changes:
- Swift 6 is the minimum supported language version.
HTMLSAXParseris final and can no longer be subclassed.- Oversized input throws
HTMLSAXParser.Error.inputTooLargeinstead of risking an integer conversion failure. - Parse options that libxml2 cannot represent throw
HTMLSAXParser.Error.invalidParseOptions. - The repository is distributed through Swift Package Manager only. The legacy Xcode project and demo application have been removed.
- The package imports the Apple SDK's libxml2 module directly. The old C error-callback shim and custom build flags are no longer required.
The synchronous parsing methods, events, parse options, and entity-encoding methods otherwise retain their existing names and behavior.
HTMLSAXParser is available under the Apache License 2.0. See LICENSE.