Qore XML Module
1.5
|
XML functionality in the Qore xml module is provided by the libxml2 library, which provides a powerful, stable, clean, and thread-safe basis for XML integration in Qore. XML provides a way to describe hierarchical data, and thanks to libxml2, the xml module allows for easy serialization and deserialization between XML strings and Qore data structures.
This module is released under a choice of two licenses:
The module is tagged as such in the module's header (meaning it can be loaded unconditionally regardless of how the Qore library was initialized).
To use the module in a Qore script, use the %requires
directive as follows:
Classes provided by this module:
Also included with the binary xml module:
The following constants give information about the availability of XML functionality (dependent on libxml2 features at compile time):
XML Option Constants
Name | Type | Description |
HAVE_PARSEXMLWITHRELAXNG | bool | Indicates if parse_xml_with_relaxng() and Qore::Xml::XmlReader::relaxNGValidate() are available |
HAVE_PARSEXMLWITHSCHEMA | bool | Indicates if parse_xml_with_schema() and Qore::Xml::XmlReader::schemaValidate() are available |
If either of the above constants are False
, then calling any of the dependent functions or methods will result in a run-time exception.
This section describes automatic XML serialization and deserialization; for iterative or user-controlled XML parsing, see XML Classes.
XML serialization (conversion from Qore data structures to XML strings) in the xml module relies on the fact that Qore hashes retain insertion order, which means that conversion to and from Qore data structures and XML strings can be done without data loss and without reordering the XML elements. In general, XML serialization is relatively straighforward, but there are a few issues to be aware of, particularly regarding element attributes and lists. These issues are described in the following paragraphs.
First, a straightforward example:
This produces the following result
<?xml version="1.0" encoding="UTF-8"?> <record> <name> <first>Fred</first> <last>Smith</last> </name> </record>
To set XML attributes, the Qore value must be a hash and the attributes are stored in another hash in the key "^attributes^"
. That is; the value of the "^attributes^"
key must be a hash, and each member of this hash will represent an attribute-value pair.
For example:
This produces the following results:
<?xml version="1.0" encoding="UTF-8"?> <record type="customer"> <name> <first>Fred</first> <last>Smith</last> </name> </record>
If instead we wanted to have text instead of child data under the "record" node, we must set the "^value^"
key of the hash along with the "^attributes^"
key as follows:
Giving the following results:
<?xml version="1.0" encoding="UTF-8"?> <record type="customer">NO-RECORD</record>
Arrays are serialized with repeating node names as follows:
Producing the following results:
<?xml version="1.0" encoding="UTF-8"?> <record type="customer"> <part>part-02-05</part> <part>part-99-23</part> <part>part-34-28</part> </record>
It gets a little trickier when a key should repeated at the same level in an XML string, but other keys come between, for example, take the following XML string:
<?xml version="1.0" encoding="UTF-8"?> <para>Keywords: <code>this</code>, <code>that</code>, and <code>the_other</code>.</para>
It's not possible to use a list, because text is required in between. As described earlier, the "^value^"
hash key can be used to serialize text in an XML string. In this case, we need to have several text nodes and several code nodes in a mixed-up order to give us the XML string we want. Because qore hases have unique keys (we can't use the same key twice in the same hash), we resort to a key naming trick that allows us to virtually duplicate our key names and therefore arrive at the XML string we want. We do this by appending a '^'
character to the end of the key name and then some unique text. When serializing hash keys, any text after (and including) the '^'
character is ignored, therefore we can add unique text to the special XML element name prefix to ensure that the input hash contains the data needed so that it will be serialized in the right order to the XML string as in the following example:
Resulting in:
<?xml version="1.0" encoding="UTF-8"?> <para>Keywords: <code>this</code>, <code>that</code>, and <code>the_other</code>.</para>
By ignoring the text after the second '^'
character, unique keys can be given in the input string, and the above code will serialize to the XML string we want. In general, by using this convention, we can properly serialize multiple out-of-order keys without losing data and still have unique names for our hash keys.
Note than when deserializing XML strings to Qore data structures, the above rules are applied in reverse. If any out-of-order duplicate keys are detected, Qore will automatically generate unique hash key names based on the above rules only if the XPF_PRESERVE_ORDER flag is given with the parse_xml(), parse_xml_with_relaxng() or parse_xml_with_schema() function calls.
Comments can be serialized by using the "^comment^"
XML element prefix (as with other special element prefixes, arbitrary text can appear after the "^comment^"
prefix to make the element name unique) as in the following example:
Resulting in:
<?xml version="1.0" encoding="UTF-8"?> <record type="customer"><!--values correspond to customer reference values-->NO-RECORD<!--see docs for more info--></record>
Also note that CDATA
text will be generated if a hash key starts with '^cdata'
; such text will not be processed for escape code substitution. When deserializing XML strings to qore data structures, CDATA text will be placed unmodified under such a hash key as well.
Functions For XML Serialization and Deserialization
Function Name | Description |
get_xml_value() | Retrieves the value of an XML element |
make_xml_fragment() | Serializes a hash into an XML string without an XML header or formatting |
make_xml() | Serializes a hash into a complete XML string with an XML header |
parse_xml() | parses an XML string and returns a Qore hash structure |
parse_xml_with_dtd() | parses an XML string and validates it against a DTD string and returns a Qore hash structure |
parse_xml_with_relaxng() | parses an XML string and validates against a RelaxNG schema string and returns a Qore hash structure |
parse_xml_with_schema() | parses an XML string and validates against an XSD schema string and returns a Qore hash structure |
Deprecated Functions For XML Serialization and Deserialization
Classes Providing XML Functionality
Class | Description |
FileSaxIterator | An iterator class for file data |
InputStreamSaxIterator | An iterator class for input streams |
SaxIterator | An iterator class for XML strings |
XmlDoc | For analyzing and manipulating XML documents |
XmlNode | Gives information about XML data in an XML document |
XmlReader | For parsing or iterating through the elements of an XML document |
XML-RPC is a lightweight but powerful XML over HTTP web service protocol. The xml module includes builtin support for this protocol as described here. You can find more information about XML-RPC, including specifications and examples at http://xmlrpc.org.
Information about Qore's XML-RPC serialization can be found below.
XML-RPC Serialization in Qore
Qore Type | XML-RPC Type | Description |
string | string | direct conversion to UTF-8 string |
integer | i4 or string | If the integer requires more than 32 bits to represent, then it is sent as a string |
float | double | direct conversion |
number | double | conversion to a double for serialization |
boolean | boolean | direct conversion |
date | iso8601 | Absolute date/time values will convert to the default time zone for the calling context for the output string if necessary. Note that relative date/time values (durations) will be serialized with the same format as absolute date/time values. |
binary | base64 | direct conversion |
list | array | direct conversion |
hash | struct | direct conversion |
all others | n/a | All other types will cause an XML-RPC-SERIALIZATION-ERROR to be raised. |
Classes Providing XML-RPC Functionality
Class | Description |
Qore::Xml::XmlRpcClient | For communicating with XML-RPC servers |
Functions Providing XML-RPC Functionality
Function Name | Description |
make_xmlrpc_call() | Serializes a hash into an XML string formatted for an XML-RPC call |
make_xmlrpc_fault() | Serializes a hash into an XML string formatted for an XML-RPC fault response |
make_xmlrpc_value() | Serializes a hash into an XML string in XML-RPC value format |
make_xmlrpc_response() | Serializes a hash into an XML string formatted for an XML-RPC response |
parse_xmlrpc_call() | deserializies an XML-RPC call string, returning a Qore hash respresenting the call information. |
parse_xmlrpc_response() | deserializies an XML-RPC response string, returning a Qore hash respresenting the response information. |
parse_xmlrpc_value() | deserializies an XML-RPC value tree, returning a Qore hash respresenting the information. |
Deprecated Functions For XML-RPC Serialization and Deserialization
All constants (and classes and namespaces) provided by this module are created under the Qore namespace (the main namespace for the Qore Programming Language).
Code with this flag makes no calculations, but rather returns a constant value. This flag is given to function and method variants that return a default value depending on the type of argument(s). When variants with this flag are resolved at parse time, a "call-with-type-errors"
warning is raised (assuming this warning is enabled), unless PO_REQUIRE_TYPES
or PO_STRICT_ARGS
is set. If PO_REQUIRE_TYPES
or PO_STRICT_ARGS
is set, then these variants are inaccessible at parse time; resolving to a variant with this flag set at parse time causes an exception to be thrown.
These variants are included for backwards-compatibility with qore prior to version 0.8.0 for functions that would ignore type errors in arguments.
This tag is equal to RUNTIME_NOOP, except no runtime effect is caused by resolving a function or method tagged with NOOP
at runtime; this tag only affects parse time resolution.
Code with this flag makes no calculations, but rather returns a constant value. This flag is given to function and method variants that return a default value depending on the type of argument(s). When variants with this flag are resolved at parse time, a "call-with-type-errors"
warning is raised (assuming this warning is enabled), unless PO_REQUIRE_TYPES
or PO_STRICT_ARGS
is set. If PO_REQUIRE_TYPES
or PO_STRICT_ARGS
is set, then these variants are inaccessible; resolving to a variant with this flag set at parse time or run time causes an exception to be thrown.
These variants are included for backwards-compatibility with qore prior to version 0.8.0 for functions that would ignore type errors in arguments.
This tag is equal to NOOP, except that RUNTIME_NOOP
is also enforced at runtime.
This flag indicates that the function or method has no side effects; it only returns a value, for example.
This tag is identical to CONSTANT except that functions or methods tagged with RET_VALUE_ONLY
could throw exceptions.
This flag indicates that the function or method has no side effects and does not throw any exceptions.
This tag is identical to RET_VALUE_ONLY except that functions or methods tagged with CONSTANT
do not throw exceptions.
Code with this flag is deprecated and may be removed in a future version of this module; if a variant with this flag is resolved at parse time, a "deprecated"
warning is raised (assuming this warning is enabled).
Changes and Bug Fixes in This Release
FileLocationHandler
module when retrieving WSDLs (issue 3781)WebService
class (issue 2793)Changes and Bug Fixes in This Release
soapAction
values would cause an invalid error to be thrown even if there were unique paths for each operation (issue 2871)token
and normalizedString
types (issue 2859)simpleType
definitions with union
members (issue 2855)xmlns
attribute and no value (issue 3367)err
string (must correspond to the fault name) (issue 2804)wsdl_set_global_compat_empty_string_is_nothing()
function and the "compat_empty_string_is_nothing"
option for the WebService
class for backwards compatibility with older versions of the WSDL module (issue 2754)"compat_allow_any_header"
option for the WebService
class for backwards compatibility with older versions of the WSDL module (issue 2765)soaputil
to import XSDs automatically when parsing WSDLs (issue 2784)Changes and Bug Fixes in This Release
SalesforceSoapConnection
classSoapConnection
classcomplexTypes
(issue 975)complexType
declarations (issue 984)complexType
extentions (issue 985)elementFormDefault="qualified"
declarations when the value differs between schemas (issue 1112)xsi:type
information was serialized when not necessary (issue 1120)WSDL::WSMessageHelper
to generate sample messagesGET/POST
bindings (issue 1116)Changes and Bug Fixes in This Release
SalesforceSoapClient::callOperation()
in the SalesforceSoapClient module to respect the soapaction
header (issue 1659)Changes and Bug Fixes in This Release
WSOperation::serializeRequest()
to allow the SOAPAction header to be overridden in each request (issue 1226)SoapClient::callOperation()
method (issue 1226)Changes and Bug Fixes in This Release
"integer"
types are returned as integers when possible"charset=..."
value in HTTP headers (issue 906)"^header^"
key in top-level hash response to specify SOAP headers in the response messageChanges and Bug Fixes in This Release
Changes and Bug Fixes in This Release
"Content-Type"
request header