Delphi中XML转JSON方法及GET请求返回XML异常排查
问题解答
一、Delphi中XML转JSON的实现方式
Delphi可以通过多种方式实现XML到JSON的转换,以下是两种常见方案:
1. 使用Delphi自带组件手动转换
通过TXMLDocument解析XML内容,遍历节点后手动构建JSON结构:
uses Xml.XMLDoc, Xml.XMLIntf, System.JSON; function XMLToJSON(const XMLContent: string): string; var XMLDoc: TXMLDocument; RootNode: IXMLNode; JSONObj: TJSONObject; procedure ProcessNode(XMLNode: IXMLNode; JSONParent: TJSONValue); var I: Integer; ChildJSON: TJSONObject; ChildArray: TJSONArray; begin if XMLNode.HasChildNodes then begin if XMLNode.ChildNodes.Count > 1 and (XMLNode.ChildNodes[0].LocalName = XMLNode.ChildNodes[1].LocalName) then begin // 处理数组类型节点 ChildArray := TJSONArray.Create; TJSONObject(JSONParent).Add(XMLNode.LocalName, ChildArray); for I := 0 to XMLNode.ChildNodes.Count - 1 do begin ChildJSON := TJSONObject.Create; ChildArray.Add(ChildJSON); ProcessNode(XMLNode.ChildNodes[I], ChildJSON); end; end else begin // 处理普通节点 for I := 0 to XMLNode.ChildNodes.Count - 1 do begin if XMLNode.ChildNodes[I].IsTextElement then TJSONObject(JSONParent).Add(XMLNode.ChildNodes[I].LocalName, XMLNode.ChildNodes[I].Text) else begin ChildJSON := TJSONObject.Create; TJSONObject(JSONParent).Add(XMLNode.ChildNodes[I].LocalName, ChildJSON); ProcessNode(XMLNode.ChildNodes[I], ChildJSON); end; end; end; end; end; begin XMLDoc := TXMLDocument.Create(nil); JSONObj := TJSONObject.Create; try XMLDoc.LoadFromXML(XMLContent); XMLDoc.Active := True; RootNode := XMLDoc.DocumentElement; ProcessNode(RootNode, JSONObj); Result := JSONObj.ToString; finally XMLDoc.Free; JSONObj.Free; end; end;
2. 使用第三方库简化转换
借助SuperObject、mORMot等开源库可以大幅简化代码,以SuperObject为例:
uses SuperObject; function XMLToJSON(const XMLContent: string): string; var SO: ISuperObject; begin SO := SOXml(XMLContent); Result := SO.AsJSON; end;
二、解决GET请求返回XML而非JSON的问题
你的代码核心问题在于请求头设置错误:
ContentType用于告知服务器请求体的格式,但GET请求通常没有请求体,这个头对GET请求无效。- 服务器返回XML是因为你未明确告知它你需要JSON格式的响应,而Postman默认会发送
Accept: application/json头,因此能拿到正确结果。
修改代码的关键步骤
- 移除冗余的
ContentType设置(你既通过属性又通过自定义头重复设置,属于无效操作) - 添加
Accept头,明确指定接收JSON格式响应
修改后的关键代码片段:
// 替换原请求头设置部分 idHttps.Request.Clear; idhttps.Request.Method := 'GET'; // 移除这两行冗余设置 // idhttps.Request.ContentType := 'application/json'; // idhttps.Request.CustomHeaders.Add('ContentType:application/json'); // 添加Accept头指定接收JSON idhttps.Request.Accept := 'application/json'; idhttps.Request.CustomHeaders.Add('keycode:ACCESSCODE'); // 其他设置保持不变...
另外,可直接使用TIdHTTP.Get的字符串重载简化代码,无需手动处理流:
// 替换原流操作代码 Result := idhttps.Get(APIURL);
内容的提问来源于stack exchange,提问作者SangPro
相关产品推荐
相关产品推荐

