jindw / xmldom

A PURE JS W3C Standard based(XML DOM Level2 CORE) DOMParser and XMLSerializer.
Other
819 stars 265 forks source link

Allow passing function to XMLSerializer.serializeToString for converting entities #254

Closed PieterScheffers closed 5 years ago

PieterScheffers commented 5 years ago

This pull request adds the ability to pass an extra function to XMLSerializer.serializeToString. This function gets the value or data of an TEXT or ATTRIBUTE node and should return with the entities replaced.

The reason is because in my case I needed single quotes and new lines also replaced by ' and 
 respectively in attribute values. But this is not standard compliant I guess. There are a lot of other implementations out there. So if you need to build an XML for such an XML reader it is good when you can replace the entities you want and leave the entities you don't want replaced.

PieterScheffers commented 5 years ago

Example implementation:

const NodeType = {
  ATTRIBUTE_NODE:  2,
  TEXT_NODE: 3
}

const xml = xmlSerializer.serializeToString(doc, isHtml, null, (nodeType, value) => {
  const xmlEncoder = value => {
    switch (value) {
      case '<': return '&lt;'
      case '>': return '&gt;'
      case '&': return '&amp;'
      case '"': return '&quot;'
      case "'": return '&apos;'
      default:
        return '&#' + value.charCodeAt().toString().padStart(2, '0') + ';'
    }
  }

  switch (nodeType) {
    case NodeType.ATTRIBUTE_NODE:
      return value.replace(/[\t\n\r'"&<>]/g, xmlEncoder)
    case NodeType.TEXT_NODE:
      return value.replace(/[&<>]/g, xmlEncoder)
    default:
      return value
  }
})