I'm having a problem with the Dom
class and its automatic escaping of strings added via Dom.XmlNode.addTextNode(text)
and I'm not sure if I am doing it wrong and this is expected behavior or if this is a bug in the method.
Given a string: Escaping special characters: < " ' > & these should all be escaped
What I expected to happen was no automatic escaping of text by the Dom
class, creating text nodes with unescaped entities and to need to use the String.escapeXml()
method to sanitize the string myself.
However, due to the automatic escaping that is happening in the .addTextNode()
method (or maybe in .toXmlString()
), the result is double-escaped entities. (i.e. &amp;
)
My understanding is that there are 5 entities that should be escaped in XML. < " ' > &
Source: List of XML and HTML character entity references
Unfortunately, based on my testing it looks like the .addTextNode()
method only escapes <
and &
. So, I cannot rely on the method to escape the proper characters on my behalf, and I cannot pre-escape the string as it will result in double-escaped entities.
Exec Anon:
String bookTitle = 'XML Escaping';
String bookSubject = 'Escaping special characters: < " \' > & these should all be escaped';
system.debug('Subject: ' + bookSubject);
// create the Document
Dom.Document xmlDoc = new Dom.Document();
// create the root node & one child node with two child nodes containing text
dom.XmlNode DocumentRoot = xmlDoc.createRootElement('DocumentRoot', 'someNS', '');
dom.XmlNode BookInfo = DocumentRoot.addChildElement('BookInfo', null, null);
BookInfo.addChildElement('Title', null, null).addTextNode(bookTitle);
BookInfo.addChildElement('Subject', null, null).addTextNode(bookSubject);
// output the results
String xmlAsString = xmlDoc.toXmlString();
system.debug('> : ' + xmlAsString.contains('>'));
system.debug('< : ' + xmlAsString.contains('<'));
system.debug('& : ' + xmlAsString.contains('&'));
system.debug('" : ' + xmlAsString.contains('"'));
system.debug('' : ' + xmlAsString.contains('''));
// for good measure
system.debug(xmlAsString);
Results:
Subject: Escaping special characters: < " ' > & these should all be escaped
> : false
< : true
& : true
" : false
' : false
<?xml version="1.0" encoding="UTF-8"?>
<DocumentRoot xmlns="someNS">
<BookInfo>
<Title>XML Escaping</Title>
<Subject>Escaping special characters: < " ' > & these should all be escaped</Subject>
</BookInfo>
</DocumentRoot>
- Is this a bug?
- Am I building a node containing text that may contain unsafe characters incorrectly?
- Is there an alternative using the
Dom
classes?
(I don't desire to build the XML output via strings by hand.)
Update:
In the end, this wasn't a problem with the entities in the XML structure but was actually a problem that stemmed from forgetting to UTF-8 encode the raw XML string when it was used in a application/x-www-form-urlencoded
payload and sent out as an HTTPRequest. Don't forget your encoding!
EncodingUtil.urlEncode(xmlAsString, 'UTF-8');