Я собираюсь написать «руководство» по моему собственному вопросу, в котором не используется XSLT, а вместо этого используется IP * Works! Компоненты Delphi , на которые у нас есть подписка.
Это может, по крайней мере, дать другим доступный вариант или приблизительное представление о том, как «сделать свой собственный выбор».
Используем IP * Работает! TipwJSON и TipwXML компоненты.
Хитрость заключается в том, чтобы перехватить синтаксический анализ компонента JSON и затем записать обнаруженные данные в компонент XML.
Это код из тестового приложения, показывающий, как мы это сделали (я оставил код для входа):
TJSONTOXML = class(TIpwJSON)
private
FXML : TipwXML;
FLogLevel : Integer;
procedure ShowLogLine(AMsg: String);
procedure InterceptJSONStartElement(Sender: TObject; const Element: string);
procedure InterceptJSONEndElement(Sender: TObject; const Element: string);
procedure InterceptCharacters(Sender: TObject; const Text: string);
function GetXML: String;
public
property XML: String read GetXML;
constructor Create(AOwner: TForm; ALogLevel: Integer); overload; // For now testing on a Form
end;
constructor TJSONTOXML.Create(AOwner: TForm; ALogLevel: Integer);
begin
inherited Create(AOwner);
FLogLevel := ALogLevel;
Self.BuildDOM := false;
Self.OnStartElement := InterceptJSONStartElement;
Self.OnEndElement := InterceptJSONEndElement;
Self.OnCharacters := InterceptCharacters;
FXML := TipwXML.Create(nil);
end;
procedure TJSONTOXML.InterceptJSONEndElement(Sender: TObject; const Element: string);
begin
if Element = '' then // End of array
begin
if FLogLevel > 2 then ShowLogLine('JSON parse EndElement - Array');
FXML.EndElement;
end
else
begin
if FLogLevel > 2 then ShowLogLine('JSON parse EndElement - Element: ' + Element);
FXML.EndElement;
end;
end;
procedure TJSONTOXML.InterceptJSONStartElement(Sender: TObject; const Element: string);
begin
if Element = '' then // Start of array
begin
if FLogLevel > 2 then ShowLogLine('JSON parse StartElement - Array');
FXML.StartElement('ARRAY','');
end
else
begin
if FLogLevel > 2 then ShowLogLine('JSON parse StartElement - Element: ' + Element);
FXML.StartElement(Uppercase(Element),'');
end;
end;
procedure TJSONTOXML.ShowLogLine(AMsg: String);
// Use WM_COPYDATA to send log info to form
var CopyDataStruct: TCopyDataStruct;
begin
CopyDataStruct.dwData := 0;
CopyDataStruct.cbData := 2 + 2 * Length(AMsg);
CopyDataStruct.lpData := PChar(AMsg);
SendMessage((Owner as TForm).Handle, WM_COPYDATA, (Owner as TForm).Handle, lParam(@CopyDataStruct));
end;
function TJSONTOXML.GetXML: String;
begin
FXML.EndElement;
Result := FXML.OutputData;
end;
procedure TJSONTOXML.InterceptCharacters(Sender: TObject; const Text: string);
var lText: String;
begin
// Always surrounded by quotes, remove:
lText := StripQuotes(Text);
if FLogLevel > 2 then ShowLogLine('JSON parse characters: ' + lText);
FXML.PutString(lText);
end;
С этим вы можете
lJSONToXML := TJSONTOXML.Create(Self,FDataLogLvl);
// Get your JSON data from somewhere, e.g. a HTTP component. Then:
lJSONToXML.Inputdata := lData;
lJSONToXML.Parse; // The Parse method initiates the parsing that was postponed by setting BuildDom := false
// The XML is now in the OutputData property of the TipwXML and can e.g. be retrieved by our:
lOutputData := lJSONToXML.XML;
Обратите внимание, что:
- В XML нет информации о пространстве имен
- Массивы JSON при преобразовании в XML преобразуются в узлы с именем ARRAY
- Все данные хранятся в памяти