Search code examples
xmldelphidelphi-2010

Reading ° degree symbol from XML in Delphi 2010


The following XML cannot be read from Delphi because it contains an invalid ° symbol:

V1:   <Item Id="1" Description="90° Hinge"/>

It seems that Delphi does not recognise the "standard" way of doing this in XML:

V2:   <Item Id="1" Description="90&deg; Hinge"/>

Delphi does seem to handle this ok:

V3:   <Item Id="1" Description="90&#176; Hinge"/>

Since I'm getting the data from a RESTful Web Service, I don't particularly have control of the XML packets coming across, I just need to be able to read them.

Questions

  1. If V2 is the standard XML way of doing it, then why doesn't Delphi support this? Or is there a special way to handle this that I'm not aware of?
  2. Is the V1 XML badly formed to begin with? If so should I request that the RESTful interface be changed to export ° in V3 format.

Using Delphi 2010. Any help would be appreciated.


Solution

  • Just elaborating on David's answer, XML doesn't rule out any value in a text node (except for very few reserved characters) as long as they are valid in the current encoding.

    There are a few missing facts from your question:

    1. Are you producing this XML using a text editor? If this is true, then you must check what encoding are you using when saving the file. Try UTF-8. If your documents are produced using "windows" encoding then try adding an encoding attribute to the XML control tag, i.e., <?xml version="1.0" encoding="iso-8859-1"?>.

    2. Are you producing this XML using Delphi String functions? If this is the case, the encoding used by Delphi is by default UTF-8, but you can inadvertently mix it with other encodings if you are reading fragments from external sources. For this problem there is no silver bullet, except for using your XML library built-in functions to create XML.

    When I have had to deal with these things (for XML signatures, no less!) I resorted to use wrappers for any string used, and use explicit encodings (I use type Latin1String = type AnsiString(28591).)