XML to Dictionary
XML to Dictionary
Section titled “XML to Dictionary”Type: xml-to-dictionary · Package: XML Activities v1.1.1 · Output: Dictionary<string,object>
Since: v1.1.1
Converts an XML document into a dictionary you navigate with expressions, just like a JSON read with Read JSON: invoice["ID"], invoice["InvoiceLine"][0]["ID"]. Use it when you need a lot of data from the same XML: instead of one XPath query per value, you convert once and read whatever you want. In the Spanish Designer it shows up as «XML a diccionario».
How it works
Section titled “How it works”Reads the XML from xml (text) or from path (file; it honours the encoding the file declares, e.g. ISO-8859-1) and returns the content of the root element —or of the element chosen by xpath—. The element’s own name is not a key: the dictionary is directly its attributes, its text and its children. The rules:
| In the XML | In the dictionary |
|---|---|
<cbc:ID>FE-1001</cbc:ID> | "ID": "FE-1001" (text) |
Element with attributes <cbc:PayableAmount currencyID="COP">1785000.00</…> | "PayableAmount": { "@currencyID": "COP", "#text": "1785000.00" } |
Element with attributes and no text <e x="2"/> | "e": { "@x": "2", "#text": "" } |
| Element with children | A dictionary with its children (and its @… attributes) |
Repeated children (<cac:InvoiceLine> × 2) | A list in document order |
Empty element <cbc:Note/> | "" |
| Loose text between children (mixed content) | "#text", with the pieces of text joined |
CDATA section | Its content, as text |
xmlns:… declarations | They don’t appear (they are not data) |
The result is always a dictionary: if the element only has text, that text goes in "#text". Keys come out in the order they first appear in the document.
A complete example. This XML:
<Order number="P-77"> <Customer>Andina Trading</Customer> <Line><Code>A-1</Code><Quantity>2</Quantity></Line> <Line><Code>B-7</Code><Quantity>1</Quantity></Line> <Total currency="USD">150.00</Total> <Note/></Order>gives this dictionary:
{ "@number": "P-77", "Customer": "Andina Trading", "Line": [ { "Code": "A-1", "Quantity": "2" }, { "Code": "B-7", "Quantity": "1" } ], "Total": { "@currency": "USD", "#text": "150.00" }, "Note": ""}Prefixes and collisions
Section titled “Prefixes and collisions”- By default keys have no prefix (
ID,InvoiceLine). WithkeepPrefixes = truethey are written as in the document (cbc:ID,cac:InvoiceLine). - If two children from different namespaces would get the same key (e.g.
a:IDandb:ID), all of the colliding ones keep their prefix:a:IDandb:ID. An element in the default namespace uses thedefaultPrefixprefix (d:ID). If they still collide (the same prefix declared with two different URIs, or the document already usesdfor another namespace), the key is{uri}name. The rule is the same for attributes (@typeand@xsi:type). - The rule is deterministic: the same XML always gives the same keys, in document order.
Always a list
Section titled “Always a list”An element that sometimes repeats (the lines of an invoice) is a list when there are several and a dictionary (or text) when there is one. To always go through it the same way, put it in forceList: ["InvoiceLine"]. The name works with or without prefix (InvoiceLine or cac:InvoiceLine) and the rule applies to that name at any level of the document.
Values: exact text
Section titled “Values: exact text”All values stay as exact text: 1785000.00 stays "1785000.00", without losing zeros or precision, and codes with leading zeros (01) don’t change. If you turn on convertTypes (it also applies to attributes):
- Integers → integer number (
900000001); anything starting with0(except0itself) stays as text. - Decimals with a dot → exact decimal number (
1785000.00keeps its two decimals); if it has more digits than fit without rounding, it stays as text. - ISO dates → date:
2026-10-30and2026-09-30T10:15:00as a date/time without time zone;2026-09-30T10:15:00-05:00or…Zas a date with time zone. - Everything else stays as text:
+5,1e5,true, bare times (10:15:00), texts longer than 64 characters and empty values.
Required parameters
Section titled “Required parameters”None. You must provide one of xml or path (not both).
Optional parameters
Section titled “Optional parameters”| Parameter | Type | Default | Description |
|---|---|---|---|
xml | string | — | XML text. Also the embedded XML that comes out of a CDATA (see the example). Use this or path. |
path | string | — | Path of an XML file. Use this or xml. |
xpath | string | — | XPath of the element to convert, if you only need a fragment, e.g. "//cac:AccountingSupplierParty". The first match is used. Without it, the root element. |
keepPrefixes | bool | false | Keep namespace prefixes in the keys (cbc:ID instead of ID). When off, only names that would collide keep their prefix. |
forceList | List | string | — | Element names that are always a list, even when there is only one: a list (["InvoiceLine"]) or a comma-separated text ("InvoiceLine, Note"). |
convertTypes | bool | false | Convert numbers and ISO dates into number and date values. When off, everything stays as exact text. |
namespaces | Dictionary | — | Extra prefixes, or prefixes that override the document’s, for the xpath (prefix → URI). See Namespaces. |
defaultPrefix | string | "d" | Prefix of the default namespace in the xpath and in colliding keys. Empty means "d". |
Output
Section titled “Output”Returns a Dictionary<string,object> whose values are text, dictionaries (Dictionary<string,object>) and lists (List); with convertTypes, also numbers and dates.
If xpath finds nothing, the output is null (it doesn’t fail) and the log shows a warning. Check it before reading keys.
Common errors
Section titled “Common errors”| Message | Cause and fix |
|---|---|
Indicate the XML text ('xml') or the file ('path'). | Neither was provided (or both were left empty). |
Use 'xml' or 'path', not both. | Both were provided. Keep only one. |
File not found: … | The path doesn’t exist. |
The XPath must select an element. | The xpath points to an attribute, a text or a computed value. Point to the element that contains it. |
'keepPrefixes' must be true or false. / 'convertTypes' must be true or false. | The parameter’s expression returned neither a boolean nor the text true/false. |
| XML parser / DTD / size / nesting / prefix message | See Common package errors. |
An element the XML doesn’t carry simply doesn’t appear as a key: if it is optional in your documents, check that it is there before reading it.
Example: embedded electronic invoice (fictitious data)
Section titled “Example: embedded electronic invoice (fictitious data)”Colombia’s electronic invoice (DIAN, UBL 2.1) usually arrives as an AttachedDocument that carries the real invoice as text inside cac:Attachment/cac:ExternalReference/cbc:Description. Two steps: extract that text and convert it.
Read XML path = xmlPath → output: containerXML Query Text xml = container xpath = "//cac:Attachment/cac:ExternalReference/cbc:Description" → output: invoiceXmlXML to Dictionary xml = invoiceXml forceList = "InvoiceLine" → output: invoiceSet Variable name = taxId value = invoice["AccountingSupplierParty"]["Party"]["PartyTaxScheme"]["CompanyID"]["#text"]Set Variable name = number value = invoice["ID"]Set Variable name = issued value = invoice["IssueDate"]Set Variable name = due value = invoice["DueDate"]Set Variable name = total value = invoice["LegalMonetaryTotal"]["PayableAmount"]["#text"]Set Variable name = cufe value = invoice["UUID"]["#text"]For Each items = invoice["InvoiceLine"] itemVariable = line └─ Log message = "Line " + str(line["ID"]) + ": " + str(line["LineExtensionAmount"]["#text"])With the fictitious invoice used in the package tests, taxId = "900000001", number = "FE-1001", total = "1785000.00" and there are two lines.
Just a fragment, straight from the file:
XML to Dictionary path = invoicePath xpath = "//cac:AccountingSupplierParty" → output: issuerLog message = "Issuer: " + str(issuer["Party"]["PartyTaxScheme"]["CompanyID"]["#text"])Related activities
Section titled “Related activities”- XML Query Text — a single value with XPath.
- XML Query All — all the values of an XPath.
- For Each — go through the lists.