How to Create an IXMLInvoice in Datev-XML-Format.

Hi,

using Delphi XE10.1 Berlin (incl. Update 1).

I Have a XSD from Datev. There is a type called IXMLExtensionlist. It has got a function ADD, where you can get an IXMLExtension. And there is an Interface IXMLInvoice, which is from IXMLExtension. My Question:
How can I init an IXMLInvoice to get it like this example:

<?xml version="1.0" encoding="utf-8"?>
<archive version="4.0" generatingSystem="DATEV Musterdaten" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xml.datev.de/bedi/tps/document/v04.0 document_v040.xsd" xmlns="http://xml.datev.de/bedi/tps/document/v04.0">
	<header>
		<date>2016-01-04T16:21:53</date>
		<description>Musterrechnungen</description>
	</header>
	<content>
		<document>
			<extension xsi:type="Invoice" datafile="Ausgangsrechnung_4000022.xml">
				<property key="InvoiceType" value="Outgoing"/>
			</extension>
			<extension xsi:type="File" name="Ausgangsrechnung_4000022.pdf"/>
		</document>
	</content>
</archive>

Open in new window


{ IXMLDocumentDatev }

  IXMLDocumentDatev = interface(IXMLNode)
    ['{0588D283-2612-4EE4-82C9-8DAD486F5E91}']
    { Eigenschaftszugriff }
    function Get_Guid: UnicodeString;
    function Get_Type_: ShortInt;
    function Get_ProcessID: ShortInt;
    function Get_Description: UnicodeString;
    function Get_Keywords: UnicodeString;
    function Get_Extension: IXMLExtensionList;
    function Get_Repository: IXMLRepository;
    procedure Set_Guid(Value: UnicodeString);
    procedure Set_Type_(Value: ShortInt);
    procedure Set_ProcessID(Value: ShortInt);
    procedure Set_Description(Value: UnicodeString);
    procedure Set_Keywords(Value: UnicodeString);
    { Methoden & Eigenschaften }
    property Guid: UnicodeString read Get_Guid write Set_Guid;
    property Type_: ShortInt read Get_Type_ write Set_Type_;
    property ProcessID: ShortInt read Get_ProcessID write Set_ProcessID;
    property Description: UnicodeString read Get_Description write Set_Description;
    property Keywords: UnicodeString read Get_Keywords write Set_Keywords;
    property Extension: IXMLExtensionList read Get_Extension;
    property Repository: IXMLRepository read Get_Repository;
  end;

{ IXMLExtension }

  IXMLExtension = interface(IXMLNode)
    ['{D673C339-001F-4BF5-B0E7-DC68D4C8F639}']
  end;

{ IXMLExtensionList }

  IXMLExtensionList = interface(IXMLNodeCollection)
    ['{95F77EB8-0767-4CD4-8F2D-E4B3160DDF37}']
    { Methoden & Eigenschaften }
    function Add: IXMLExtension;
    function Insert(const Index: Integer): IXMLExtension;

    function Get_Item(Index: Integer): IXMLExtension;
    property Items[Index: Integer]: IXMLExtension read Get_Item; default;
  end;

{ IXMLInvoice }

  IXMLInvoice = interface(IXMLExtension)
    ['{7070599E-40D0-4435-8620-2595D84B92C0}']
    { Eigenschaftszugriff }
    function Get_Datafile: UnicodeString;
    function Get_Property_: IXMLInvoice_property;
    procedure Set_Datafile(Value: UnicodeString);
    { Methoden & Eigenschaften }
    property Datafile: UnicodeString read Get_Datafile write Set_Datafile;
    property Property_: IXMLInvoice_property read Get_Property_;
  end;

Open in new window


My Code is:

  procedure tDatevXMLObjekt.Testausgabe;
    var
      a:IXMLArchive;
      doc:IXMLDocumentDatev;
      sl:tStringlist;
      inv:IXMLInvoice;
      ext:IXMLExtension;
    begin
      a:=NewArchive;
      a.GeneratingSystem:='bla bla';
      a.Header.Date:=formatdatetime('yyyy-mm-dd',date)+'T'+formatdatetime('hh:nn:ss',now);
      a.Header.Description:='Testausgabe von Michi';
      a.Header.Consultantnumber:=1;
      a.Header.ClientNumber:=2;
      a.Header.ClientName:='Michi';

      doc:=a.Content.Add;
      doc.Description:='Erste Testrechnung';

//      inv:=doc.extension.Add;  //does not work
      ext:=doc.extension.Add;  //works, but I need a IXMLInvoice;

Open in new window


How can I do some kind of Typecast, how can I Init an IXMLInvoice.
migrossAsked:
Who is Participating?
 
migrossConnect With a Mentor Author Commented:
I found a workaround. I created the IXMLextension and set the properties in the extension manually with IXMLNode.SetAttribute. There was no other chance in this case, but it worked.
0
 
ste5anSenior DeveloperCommented:
Without knowing the XSD, assuming that IXMLInvoice is derived from IXMLExtensions:

You cannot use Add() like this. You need to create a XMLInvoice first and add this instance.
0
 
migrossAuthor Commented:
Well, thats exactly my Problem.

It is descreibed as an Interface:

IXMLInvoice = interface(IXMLExtension)

I don't know how to create a IXMLInvoice. There is no Constructor as in a class-Object and I don't know how it gets in the Extensionlist. Perhaps my question is too easy, perhaps it's not possible. I never created an "Interface-Object" that is derived from another Interface. In XSD-Files I imported to Delphi the interface types where always clearly defined on their own, never derived.

The XSD-File is attached. While Import you must rename IXMLDocument to IXMLDocumentXYZ, so that Delphi doesn't have errors using it's own IXMLDocument.
Document_v040.xsd
0
Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

 
ste5anSenior DeveloperCommented:
Please attach your generated code from that XSD.
0
 
migrossAuthor Commented:
Here is the code.
Document_v040.pas
0
 
ste5anSenior DeveloperCommented:
{ TXMLInvoice }

  TXMLInvoice = class(TXMLExtension, IXMLInvoice)
  protected
    { IXMLInvoice }
    function Get_Datafile: UnicodeString;
    function Get_Property_: IXMLInvoice_property;
    procedure Set_Datafile(Value: UnicodeString);
  public
    procedure AfterConstruction; override;
  end; 

Open in new window

0
 
migrossAuthor Commented:
Well, I now there are "T"XML-Objects. But there the functions are Protected, so I can't use then from outside. Or am I wrong? Should I declare all properties again or move them to public?

var
  invoice:TXMLInvoice;
begin
  invoice.datafile:='blabla.xml'; //is not possible in this Object.

Open in new window


I would prefer not to declare there, because the next version of XSD will come, and then I should have to do this work again.

Could you give me a sample using the first code "Testausgabe" I posted, where you define a TXMLInvoice and create it? Which ist the Domnode, which the Parentnode? Then the Parameters must all be tXMLNode and not IXMLNode. none of the properties are available in TXML... . I am really weird at the moment.
0
 
ste5anSenior DeveloperCommented:
As I don't know how to use this special XSD and its classes, this is just a guess:

The normal workaround is to declare your own derived classes from those TXMLxxx class. Then you have access to the methods.
0
 
migrossAuthor Commented:
it works
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.