Bump swift-actions/setup-swift from 1.22.0 to 1.23.0
Bumps swift-actions/setup-swift from 1.22.0 to 1.23.0.
updated-dependencies:
- dependency-name: swift-actions/setup-swift dependency-type: direct:production update-type: version-update:semver-minor …
Signed-off-by: dependabot[bot] support@github.com
XMLWrangler
Easily deal with XMLs in Swift.
Installation
Add the following dependency to your
Package.swift:Compatibility
Usage
XMLElement
Every element in an XML is represented by the
XMLElementstruct. It has three properties,namewhich reflects the element’s tag name,attributeswhich contains all attributes of the element andcontentwhich describes the content of the element. The content is an collection whoseElementis an enum. The enum has two cases:.stringand.element. The order in the collection is the order in which the content has been found. So if an element first contains some text, then contains a child element and finally again some text,contentwill contain a.stringwhose associatedStringPartis the first text. Next there would be a.elementwhose associatedXMLElementwould be the child element. Finally, there would be another.stringwith the last text.While you can create an
XMLElementwith a content of[.string("abc"), .string("def"), .element(XMLElement(name: "test"))], and it would also lead to valid XML, it could be cleaned up to[.string("abcdef"), .element(XMLElement(name: "test"))]. To achieve that, it’s recommended to use the variousappendfunctions onXMLElement.contentor evenXMLElementdirectly when you can’t assure that the content is cleaned upon creation. If your element was created with an empty content ([]), and you append each of the content elements above, theappendfunctions make sure that they append the “def” string to the first “abc” string instead of adding another.stringto the content. If for some reason you still end up with a situation where your content has consecutive.stringelements, there’s a convenience functioncompress()(or it’s non-mutating siblingcompressed()), which merges these.stringelements into one.An
XMLElementcan be compared to another element and is considered equal if all three properties (name,attributesandcontent) are equal. This means that for a big tree, all children of the root element will be compared. So be careful when comparing big trees and fall back to manually comparingnameand/orattributesif necessary.XMLElementalso conforms toIdentifiableand uses thenameasid.Both, serializing and parsing XMLs with XMLWrangler relies on
XMLElement.Parsing XMLs
Parsing existing XMLs can be done using the
Parserclass. You can instantiate a parser with either a givenDataobject or aStringcontaining the XML.Once you have a parser ready, you can call
parse()on it, and it’ll try to parse the XML. If that succeeds, it’ll return the parsed root object. Otherwise it throws whatever error happend along the way. Errors thrown are the ones created byFoundation.XMLParser.In this example,
root.name.rawValuewould of course be"root".rootElement.contentwould contain two.elements. The first would have a associatedXMLElementwith anameof"child1"and an emptycontent. ThenameofXMLElementof the second.elementwould be"child2"and its content would contain one.stringhaving"some text"associated.root.attributeswould contain the value"myvalue"for the key"myattr".Serializing XMLElements
Since you can parse XMLs, you can also convert an
XMLElementto a String. For this, there are two initializers onStringadded in XMLWrangler. The first one just converts anXMLElementinto aString. This happens by creating an opening and ending tag (where the beginning tag contains theattributesif available) and putting thecontentof the element in between. Ifcontentis empty, then no ending tag is created and the opening tag is directly closed with/>. Also,contentis compressed (using the aforementionedcompressfunction) before being serialized.If the traditional XML header should also be added, there’s a second initializer which takes a version and a document encoding as additional parameters, but otherwise follows the same rules:
For more information on
Versionsee SemVer but note that onlymajorandminorare used for XMLs. Please note that currently XMLWrangler only supports serializing documents for the following encodings:Both initializers can take an additional parameter
optionswhich contains a set of options to control the serialization behaviour. Currently the following options are possible:.pretty: Use pretty formatting. This adds newlines around the tags to make the resulting XML more readable. This is usually not needed for processing XML..singleQuoteAttributes: When this option is present, then attributes of elements will be enclosed in single quotes (‘) instead of double quotes (“).Type safety
XMLWrangler will always extract all content and attributes as
String. This is because XML itself does not differentiate between types like e.g. JSON does. However, there are many helper functions to safely look up and convert content and attributes of anXMLElement:XMLElement.elements(named:)XMLElement.element(at:)XMLElement.attribute(for:).RawRepresentableyou don’t need to pass aconverter):XMLElement.convertedAttribute(for:converter:)XMLElement.stringContent()XMLElement.convertedStringContent(converter:)All these methods throw an error (
LookupError) when something went wrong instead of returning optionals. If you prefern an optional, you can always usetry?. For more information also check the header docs which describe these methods a little closer.Possible Features
While not yet integrated, the following features might provide added value and could make it into XMLWrangler in the future:
Documentation
The API is documented using header doc. If you prefer to view the documentation as a webpage, there is an online version available for you.
Contributing
If you find a bug / like to see a new feature in XMLWrangler there are a few ways of helping out:
License & Copyright
See LICENSE file.
Copyright © 2016-2021 ser.soft GmbH.