//===----------------------------------------------------------------------===// // Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. //===----------------------------------------------------------------------===// /// An XML renderer. @ModuleInfo { minPklVersion = "0.31.0" } module pkl.xml /// Renders values as XML. /// /// Values are rendered as follows depending on their type: /// /// - `Int`, `Float`, `Boolean`, `String`: XML text node /// - `List`, `Set`, `Listing`: sequence of XML text nodes or XML elements (depending on element types) /// - `Map`, `Mapping`, `Typed`: sequence of XML elements (`null` values are skipped) /// - `Dynamic`: sequence of XML text nodes and/or XML elements (depending on member types; `null` value are skipped) /// /// For more control over XML rendering, use [Element()], [Inline], [Comment], and [CData]. /// These DOM-style objects can be used exclusively or mixed and matched with "normal" Pkl objects. /// /// To set the name and attributes of the XML document's root element, /// use [rootElementName] and [rootElementAttributes]. class Renderer extends ValueRenderer { extension = "xml" /// The characters to use for indenting output. indent: String = " " /// The XML version to use. xmlVersion: *"1.0" | "1.1" /// The name of the XML document's root element. rootElementName: String(!isEmpty) = "root" /// The attributes of the XML document's root element. rootElementAttributes: Mapping external function renderDocument(value: Any): String external function renderValue(value: Any): String } /// Creates an XML element with the given name. /// /// Use this method to directly define an XML element /// instead of relying on the default rendering of Pkl values. /// /// To define the XML element's attributes, set the [attributes] property of the `Element` object: /// ``` /// order = xml.Element("order") { /// attributes { /// ["date"] = "2020-03-21" /// } /// } /// ``` /// /// To define the XML element's content, add child values (normally also called "elements") to the `Element` object: /// ``` /// order = xml.Element("order") { // element with one child /// xml.Element("item") { // element with two children /// xml.Element("name") { "banana" } // element with one child /// xml.Element("quantity") { 42 } // element with one child /// } /// } /// ``` function Element(_name: String(!isEmpty)): Dynamic = new { _isXmlElement = true name = _name attributes = new Mapping {} isBlockFormat = true } /// Creates an [Inline] directive for [_value]. function Inline(_value: Object | Collection | Map): Inline = new { value = _value } /// Inlines the members of [value] into the enclosing XML element, /// without rendering an XML element for [value] itself. class Inline { value: Object | Collection | Map } /// Creates an XML [Comment] with the given [_text]. function Comment(_text: String): Comment = new { text = _text } /// An XML comment. class Comment { text: String(!contains("--")) isBlockFormat: Boolean = true } /// Creates an XML [CData] section with the given [_text]. function CData(_text: String): CData = new { text = _text } /// An XML CDATA section. class CData { text: String }