Ignition 7.9 Dropdowns Work When Translation XML Is Escaped

Tom Garrett7 min read
HMI / SCADAOther ManufacturerTroubleshooting
Licensed PE Working through this on a live machine? A Maine-licensed engineer can take it from here — included with IMD hardware, by the hour for everything else. Book an engineer

Ignition 7.9 shows the Step Code translation list when the generated list contains correctly spelled <stringpair> elements and every key and value is escaped as markup text. Fix the misspelled element first, then check for unescaped characters such as & in the data; a cell update binding cannot compensate for a translation map that fails to parse.

Find whether the Step Code list fails before or after parsing

The initial script builds separate serialized lists for Item, Unit, and Step, then assigns each one to a table property. The observed failure is limited to the Step Code column: its translation data exists, but the table customizer displays no mappings. That points first to the generated Step list's structure or content, rather than to the contents of the other two lists.

Two separate defects appear in the Step path. The original code spells the opening element <stringpaiir>, while the closing element is </stringpair>. Correcting the spelling fixes that structural mismatch. The later investigation found another issue: data values can contain special characters that must be escaped before insertion into markup. A malformed element and an unescaped value can both prevent the map from being interpreted correctly.

Observation Likely check Where to inspect
One column has no mappings in the customizer Compare its generated list structure and content with a working column translateStepStr and the Step Code translation property
Correcting the element spelling changes the result, but data still fails Check for unescaped markup characters in keys and values Each generated <key> and <value> text node
Mappings appear, but the cell does not offer the expected options Check the table's translation-list setting and cell binding separately Table customizer and cell update binding

Understand why one character can invalidate the whole map

The script constructs a markup-formatted list by concatenating opening and closing tags around dataset values. The resulting string is not plain display text: characters in a value are interpreted as markup syntax. An ampersand begins an entity reference, and characters such as less-than can be read as the start of a tag. If a data value contains markup-significant characters without proper escaping, the parser can reject or misread the serialized list. That can make an otherwise populated translation property appear empty.

The Item and Unit paths and the Step path are generated independently. Thus, successful mappings in two columns do not validate the third column's serialized string. The Step path has its own element spelling, source dataset column, string conversion, and property assignment. Compare the exact generated value for each column rather than assuming the shared pattern makes every path equivalent.

Escaping must be applied to text inserted between tags, not to the list's structural tags. Escape both keys and values: either field may contain source data. Do not escape the complete list after concatenating it, because that would also turn the required structural markup into literal text.

Generate the Step list with valid element names and escaped text

Use a dedicated escaping operation for every dataset value inserted into a key or value node. The evidence identifies Apache Commons Lang3's StringEscapeUtils.escapeHtml4() as available in Ignition, and uses it in the Step value construction. Apply it consistently to the key and to every value that can contain special characters. The example below follows the demonstrated dataset columns for Step: column 0 is the key and column 3 is the displayed value.

from org.apache.commons.lang3 import StringEscapeUtils

tSStr = '<list>'
ds = event.source.translateStep
for row in range(ds.rowCount):
    key = StringEscapeUtils.escapeHtml4(str(ds.getValueAt(row, 0)))
    value = StringEscapeUtils.escapeHtml4(str(ds.getValueAt(row, 3)))
    tSStr += '<stringpair><key>' + key + '</key><value>' + value + '</value></stringpair>'
tSStr += '</list>'
event.source.translateStepStr = tSStr

This example addresses the discovered markup issue and fixes the misspelled tag. Review the dataset's null or missing-value convention before converting values to strings: the original script checks the literal result 'None' for an Item field and creates an empty value in that case, but does not specify equivalent Step handling. Choose the desired blank-value behavior explicitly and use it consistently. Also validate the generated output with the table's translation parser, since the required property format—not merely a visually plausible string—determines acceptance.

A second suggested approach in the evidence is Python's urllib quote() or quote_plus(). Those functions encode text for URLs; they do not escape text for markup. For content inserted into this list structure, use markup-aware escaping rather than URL encoding.

Keep translation-list generation separate from the cell binding

The cell update binding and the translation map solve different parts of the interaction. The binding updates the cell, while the generated translation list supplies the key-to-display-value pairs used by the table. A binding can be configured correctly while the translation list remains malformed, and a valid list does not by itself establish that the cell binding is configured as intended.

  1. Correct the Step element spelling so the opening and closing tags match exactly.
  2. Escape every dataset key and value before appending it between markup tags.
  3. Assign the completed Step list to event.source.translateStepStr and inspect the resulting property.
  4. Check the table customizer's translation-list configuration for the Step Code column.
  5. Test the cell update binding after the list is recognized, so binding behavior does not obscure a parsing fault.

The reported attempt to manually select “Use Translation List” did not resolve the issue while the generated Step mapping was invalid. Treat that setting as a configuration check after correcting the serialized list, not as a substitute for valid markup.

Verify the parsed mappings and runtime dropdown independently

Verify at the property level and at the cell level. First inspect the completed translateStepStr: it must have one list wrapper, matching stringpair tags for each row, and properly escaped key and value text. Then confirm that the table customizer displays the Step Code mappings. Finally test the cell's dropdown with representative data, including values containing ampersands or other markup-significant characters.

When the customizer shows mappings but the runtime dropdown does not behave as expected, return to the table's “Use Translation List” option and the cell update binding. When the customizer shows no mappings, stay focused on the generated Step string: inspect the property assignment, tag spelling, row/column indexes, and escaping. This separation identifies whether the failure occurs while the map is built and parsed or later in the table interaction.

Prevent repeat failures in other translation columns

Do not assume the other columns are safe merely because they currently display mappings. The Item path builds values from dataset columns 0 and 1, and the Unit path uses columns 0 and 2; the Step path uses columns 0 and 1 in the original code, while the later working script uses column 3 for the Step value. Confirm the intended dataset layout and indexes against the actual translation dataset before changing the code. A wrong column can produce unexpected labels even when the markup is valid.

The initial Item logic treats the string representation 'None' as a special case and emits an empty value. The later script applies this special handling to Item but not Unit or Step. Decide how blank or missing values should appear in each list, and encode that rule deliberately rather than relying on incidental string representations.

The demonstrated str.replace('&', '&amp;') correction addresses an ampersand, but the author explicitly notes it does not cover other special characters. A single-character replacement is therefore an incomplete escaping strategy. Use one markup-aware escaping function on all inserted text nodes, and preserve the structural tags as markup.

Ignition 7.9 translation-map FAQ

Why does the Ignition 7.9 dropdown show no Step Code mappings?

Check the generated Step list for mismatched tags and unescaped data. The original opening tag is misspelled as stringpaiir; correct it to stringpair, then escape keys and values before building the list.

Why does an ampersand break a translation value?

An ampersand is markup-significant inside the serialized list and must be escaped as text. The supplied example replaces & with &amp;, but an escaping utility is more complete than handling that one character alone.

Why does checking “Use Translation List” not fix the dropdown?

The option cannot repair a malformed translation string. Correct the markup and inspect translateStepStr first, confirm mappings appear in the customizer, then test the cell update binding and dropdown.

Stop editing the cell binding if the generated list remains absent after correcting its structure and escaping; capture the property value and the table configuration for diagnosis. Escalate to official Inductive Automation support when a valid list still fails to parse or the customizer and runtime behavior disagree.

Back to blog