Use S() or nodeValue()?
Contents
- Introduction
- Rules for when to choose :S() or :nodeValue()
- Background Information
- How :S() and :nodeValue() work and how they differ
- What is the difference between :S() and tostring()?
Introduction [top]
Confused about which string conversion function to use? This FAQ provides an explanation of when to use :nodeValue()
and when to use:S()
. We will explain how each function works, how they are different, and how to apply each one correctly (including any exceptions to the rules). To really understand how these functions work, nothing beats playing around with the code on the examples page.
If you are in hurry (and don’t need explanations), then just read the basic rules below.
Rules for when to choose :S() or :nodeValue() [top]
Just follow these two rules:
- Use
:nodeValue()
to convert a leaf node to text - Use
:S()
to serialize a non-leaf node (tree) to text
We have found that simply thinking of :S()
as “s for serialize” helps users to remember the difference.
Background Information [top]
To better understand this FAQ, you may need to read up on the following:
- The ability to read/understand simple Lua code.
- Exposure to HL7 delimiter characters.
- Exposure to XML escape sequences (called Entities in XML).
How :S() and :nodeValue() work and how they differ [top]
How does :S() work?
- The
:S()
function serializes any node into a string:- It converts non-leaf nodes (trees) into a string representation
- It will also convert leaf nodes (but we recommend using
:nodeValue()
instead)
- The
:S()
function performs escaping on values, if the protocol requires it:- For an XML node, it will convert ‘>’ to ‘>’
- For HL7 and X12 nodes, it will convert ‘&’ to ‘\T\’
- For all other node type no escaping is performed
How does :nodeValue() work?
- The
:nodeValue()
function returns a leaf node as a string value- It converts leaf nodes (trees) into a string representation
- It cannot convert non-leaf nodes (you must use
:S()
ortostring()
instead)
- The
:nodeValue()
function never performs escaping, regardless of protocol
What is the difference between :S()
and :nodeValue()
:
- The
:S()
function works for any node,nodeValue()
only works on leaf nodes - The
:S()
function performs escaping (when required),nodeValue()
never performs escaping - The
nodeValue()
function will decode (“un-serialize”) escape sequences (i.e., XML entities) when required, whereas the :S() will does not decode escape sequences and just returns the encoded text
What is the difference between :S() and tostring()? [top]
The tostring()
function works identically to :S()
, because :S()
is simply a wrapper for tostring()
. As such, you can substitute tostring()
anywhere you use :S()
. However because :S()
is not a built-in function, you need to include the “node” module to use it (you must add require 'node'
to your script).
Exceptions
Are there any occasions where using :S()
on a leaf node is a good idea? In our opinion, probably not.
However, this is not a hard and fast rule! You might find an application where it is useful to use :S()
to serialize HL7 or XML messages stored in leaf nodes. For example, you might need to store a complete message in a leaf node and return it in serialized form using :S()
.
The only real “exceptions” are Database and JSON node trees, as both return the same same value using nodeValue()
or S()
. Regardless, we recommend using nodeValue()
for consistency.
What’s Next? [top]
By now, you should understand when to use :nodeValue()
and when to use:S()
. If you are still a bit hazy about the rules, we recommend that you play around with the code in the examples provided. That said, if you remember the basic rules listed above, you cannot go wrong.