在Delphi 2010中从XML读取°度符号

Ric*_*ler 8 xml delphi delphi-2010

无法从Delphi读取以下XML ,因为它包含无效的°符号:

V1:   <Item Id="1" Description="90° Hinge"/>
Run Code Online (Sandbox Code Playgroud)

似乎Delphi 承认在XML中执行此操作的"标准"方式:

V2:   <Item Id="1" Description="90&deg; Hinge"/>
Run Code Online (Sandbox Code Playgroud)

德尔福似乎确实处理了这个问题:

V3:   <Item Id="1" Description="90&#176; Hinge"/>
Run Code Online (Sandbox Code Playgroud)

由于我从RESTful Web服务获取数据,因此我无法控制所遇到的XML数据包,我只需要能够读取它们.

问题

  1. 如果V2是标准的XML方式,那为什么Delphi不支持这个呢?还是有一种特殊的方式来处理这个我不知道的事情?
  2. V1 XML是否刚开始形成?如果是这样,我应该请求将RESTful接口更改为以V3格式导出°.

使用Delphi 2010.任何帮助将不胜感激.

Rem*_*eau 9

Delphi本身根本不解析XML.第三方XML引擎,无论是MSXML,OpenXML,AtomXML等.TXMLDocument组件和支持接口只是一个包装器框架,大部分解析都是由其他人完成的.

V1可能会或可能不会格式错误.这取决于XML的实际字符集.

V2实际上不是标准的.并非所有XML引擎都支持它.显然,您使用Delphi的那个没有.

V3是标准化的,所有XML引擎都支持该语法.

  • 关于V3,我会说"所有*以上*XML引擎支持该语法"(或者至少*应该*支持它). (2认同)

Dav*_*nan 9

V1:   <Item Id="1" Description="90° Hinge"/>
Run Code Online (Sandbox Code Playgroud)

在这里你直接编码了角色.您的代码是否可以解析此问题取决于XML文档使用的字符集.因此,如果您的XML文档使用UTF-8并且编码正确,那么您的XML代码将能够解析它.

V2:   <Item Id="1" Description="90&deg; Hinge"/>
Run Code Online (Sandbox Code Playgroud)

它使用一个命名实体,.在XML中,只有五个预定义的命名实体:quot,amp,apos,lt,gt.XML文档可以定义其他命名实体,但这是不寻常的.因此,看起来deg不是您文档的有效命名实体.

V3:   <Item Id="1" Description="90&#176; Hinge"/>
Run Code Online (Sandbox Code Playgroud)

此版本使用数字字符引用 NCR.您可以使用NCR指定任何Unicode代码点.


至于你应该做什么,我们可以立即排除命名实体.我还建议避免为所有非ASCII字符批量使用NCR.这只会导致难以理解的文件.当然,如果必须使用非Unicode识别工具来处理文档,那么使用NCR是唯一的方法.

这样我们就可以直接编码非ASCII字符了.您应确保使用UTF-8字符集正确编码XML,并且该方法可以正常工作,并且可以生成可读且干净的文档.


Leo*_*era 1

只是详细阐述 David 的答案,XML 并不排除文本节点中的任何值(除了极少数保留字符),只要它们在当前编码中有效即可。

您的问题中缺少一些事实:

  1. 您是否使用文本编辑器生成此 XML? 如果这是真的,那么您必须检查保存文件时使用的编码。尝试使用 UTF-8。如果您的文档是使用“windows”编码生成的,请尝试向 XML 控制标记添加编码属性,即<?xml version="1.0" encoding="iso-8859-1"?>.

  2. 您是否使用 Delphi 字符串函数生成此 XML? 如果是这种情况,Delphi 使用的编码默认为 UTF-8,但如果您从外部源读取片段,则可能会无意中将其与其他编码混合。对于这个问题,除了使用 XML 库内置函数来创建 XML 之外,没有什么灵丹妙药。

当我不得不处理这些事情时(对于 XML 签名,同样如此!),我对所使用的任何字符串使用包装器,并使用显式编码(我使用type Latin1String = type AnsiString(28591).)