Tutorial: Reading an empty XML TEXT element from a node tree

This post was originally written for Iguana 5 so it contains version 5 screenshots, and may contain out of date references.

This article addresses an error that occurs when reading an empty XML TEXT element. The issue is a simple one: If you have an XML element with an empty string then the node:nodeValue() function raises an “Index N is out of bounds.” error, when the desired behaviour is to return an empty TEXT node.

We show you our recommended Best Practice solution, which uses the node:text() function, from XML Techniques in the Protocols Repo. For more information and other solutions, see: Prevent errors reading from an empty XML element.

We recommend that you type in the code for each step, but we also include complete Sample Code if you prefer to paste it in and follow along.

Create the Channel [top]

  1. Create a Channel with the the following settings:
    • Source = From Translator
    • Destination = To Translator
    • Channel name = Read empty XML TEXT
  2. Click the Add Channel button to create the channel.
    Ignore the red warning messages, see resolving the commit configuration error.
  3. Open the Translator by clicking the Edit Script link at the bottom of the To Translator tab.
  4. Download and import the Read_empty_XML_TEXT_To_Translator.zip project file.
    This file contains a skeleton project and six sample XML messages.
  5. Iguana will load the project and data into the Translator, your screen should look like this:

Tutorial Instructions [top]

  1. Pass the message data to the script.
    • Iguana automatically passes the message data to the main() function
    • The message can be accessed using the Data parameter
    • No action is needed
  2. Navigate through the sample data to see errors caused by empty TEXT elements.
    Click next message button on the toolbar five times:

    You will see “Index 1 is out of bounds.” errors like this:
  3. Demonstrate that :nodeValue() is not causing the problem.
    1. Delete “:nodeValue()” from lines 7, 9 and 11
    2. Your code should look this:
    3. Navigate through the sample data again, to confirm the same errors occur.
    4. Conclusion: The error is caused by referencing an empty TEXT element.
  4. I’m still a bit confused! What exactly is causing this error?
    1. Navigate to the second message.
    2. Click the Data and XML annotations, to view their data dialogs:
    3. You can clearly see the empty TEXT element in both dialogs:
    4. Expand the “last-name” and “social-security-no” elements.
      You can clearly see that the there no TEXT element under “social-security-no”:
    5. Conclusion: The error is caused by trying to reference the non-existent TEXT element for “social-security-no”.
  5. Use the node.text() function from the xml module to resolve the issue.
    1. Replace “[1]” with “:text()” on lines 7, 9, and 11.
      Your code should look like this:
    2. Navigate through the sample data, to confirm that no errors occur.
  6. Change the code to return strings, like the original code.
    1. Notice that the :text() method is returning TEXT elements:
    2. Append “:nodeValue()” to lines 7, 9, and 11:
    3. As you can see we are now returning strings, like the original code.
      Finished code:

      Original code:
  7. That’s it you’re done!

Complete Sample Code [top]

Here is the finished code that you can cut and paste into your script.

require 'xml'

function main(Data)
   -- Parse the XML message
   local XML = xml.parse(Data)
   
   -- ORIGINAL CODE: Will cause errors with empty TEXT elements
   
   --local FirstName = XML.patients.patient["first-name"][1]:nodeValue()
   
   --local LastName = XML.patients.patient["last-name"][1]:nodeValue()

   --local SSN = XML.patients.patient["social-security-no"][1]:nodeValue()
   
   
   -- FINAL CODE: Does not cause errors with empty TEXT elements
   
   local FirstName = XML.patients.patient["first-name"]:text():nodeValue()
   
   local LastName = XML.patients.patient["last-name"]:text():nodeValue()

   local SSN = XML.patients.patient["social-security-no"]:text():nodeValue()

end

More Information [top]

Leave A Comment?