JSON в XML с использованием XSLT 3.0 - как загрузить исходный код JSON и вызвать функцию json-to-xml? - PullRequest
2 голосов
/ 19 апреля 2019

Я хочу поэкспериментировать (в коде Delphi) с XSLT 3.0 и его функцией json-to-xml () :

В XSLT 3.0 входящий документ может быть в формате JSON, а не в формате XML. Процессор может взять этот документ, использовать функцию json-to-xml () для преобразования его в определенный известный формат XML, обработать его с помощью шаблонов, а затем преобразовать полученный результат обратно в JSON (или может преобразовать его в HTML 5 среди другие форматы

Но я застрял в двух местах:

  • Как использовать строку JSON в качестве источника для преобразования? Попытка загрузить его в TXMLDocument дает мне (конечно же?) 'Некорректные' ошибки

  • Как бы я тогда применил «json-to-xml() функцию». Все примеры, которые я нашел об использовании XSLT-преобразований в Delphi, используют функцию TransformNode, как показано ниже. Такие вещи, как lDoc.Node.json-to-xml не компилируются.

.

var
  lDoc, lXSL, lRes: IXMLDocument;
  lUTF8Str        : UTF8String;
begin
  lDoc := LoadXMLData(AXMLString);
  lXSL := LoadXMLData(cRemoveNSTransform);
  lRes := NewXMLDocument;
  lDoc.Node.TransformNode(lXSL.Node,lRes);  // Param types IXMLNode, IXMLDocument
  lRes.SaveToXML(lUTF8Str);     

Кто-нибудь может указать мне правильное направление?

1 Ответ

0 голосов
/ 01 июля 2019

Я собираюсь написать «руководство» по моему собственному вопросу, в котором не используется 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
  • Все данные хранятся в памяти
...