Altova MapForce 2025 Professional Edition

In diesem Kapitel wird erläutert, wie Sie eine MapForce-Funktionsdatei (.mff) konfigurieren. Eine .mff-Datei ist eine konfigurierbare Datei im XML-Format, mit deren Hilfe Sie Funktionen aus benutzerdefinierten Java-, C#- oder C++-Bibliotheken in MapForce importieren können, so dass sie im Fenster Bibliotheken angezeigt werden. Eine .mff-Datei dient als Verbindungsglied zwischen Ihren benutzerdefinierten Bibliotheken und MapForce. Die .mff-Datei muss so konfiguriert sein, dass sie i) die Schnittstellen zu den benutzerdefinierten Funktionen definiert und ii) angibt, wo die Implementierung im generierten Code zu finden ist.

 

Achtung:

 

Die *.mff-Bibliotheksdateien müssen dem folgenden Schema gemäß gültig sein: C:\Programme\MapForceLibraries\mff.xsd. Das mff.xsd-Schema definiert die Konfiguration der benutzerdefinierten Bibliothek und dient nur zur internen Verwendung. Die Altova GmbH behält sich das Recht vor, dieses Dateiformat in neuen Releases zu ändern.

Es kann nur eine C#-, C++- oder Java-Klasse pro .mff-Datei definiert werden.

 

.mff-Beispiel für C#

Im folgenden Codefragment sehen Sie eine .mff-Datei für C++:

 

<?xml version="1.0" encoding="UTF-8"?>
<mapping version="9" library="mylib" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="mff.xsd">
  <implementations>
     <implementation language="cpp">
        <setting name="namespace" value="mylib"/>
        <setting name="class" value="Greetings"/>
        <setting name="path" value="C:\Libraries\cpp"/>
        <setting name="include" value="Greetings.h"/>
        <setting name="source" value="Greetings.cpp"/>
     </implementation>
  </implementations>
  <group name="greetings">
     <component name="sayhello">
        <sources>
           <datapoint name="ismorning" type="xs:boolean"/>
        </sources>
        <targets>
           <datapoint name="result" type="xs:string"/>
        </targets>
        <implementations>
           <implementation language="cpp">
              <function name="SayHello"/>
           </implementation>
        </implementations>
        <description>
           <short>result = sayhello(ismorning)</short>
           <long>Returns "Good morning" or "Good day", depending on the input parameter.</long>
        </description>
     </component>
  </group>
</mapping>

 

Importierte benutzerdefinierte Bibliothek

In der Abbildung unten sehen Sie, wie eine benutzerdefinierte .mff-Datei nach dem Import in MapForce aussehen könnte. Die benutzerdefinierte Bibliothek mylib erscheint als Eintrag in der Bibliotheksliste (in alphabetischer Reihenfolge sortiert) und enthält die String-Funktion sayhello.

mf_custom_lib

 

Konfigurationsschritte

Um die .mff-Datei zu konfigurieren, gehen Sie vor, wie unten beschrieben.

 

Schritt 1. Konfigurieren des Bibliotheksnamens

Der Bibliotheksname befindet sich in der .mff-Datei (siehe unten). Konventionsgemäß sind Bibliotheksnamen in MapForce in Kleinbuchstaben geschrieben, es können aber auch Großbuchstaben verwendet werden.

 

<mapping version="9" library="mylib" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="mff.xsd">

 

Im obigen Beispiel hat der im Fenster Bibliotheken angezeigte Eintrag den Namen mylib.

 

Schritt 2. Konfigurieren der Sprachimplementierungen

Das Element <implementations> ist ein obligatorisches Element. Es gibt an, welche Sprachen Ihre Bibliothek unterstützen soll und muss als Child-Element von <mapping> hinzugefügt werden (siehe Beispiel unten).

 

<!-- ... -->
<mapping version="9" library="mylib" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="mff.xsd">
  <implementations>

     <implementation language="cpp">
        <setting name="namespace" value="mylib"/>
        <setting name="class" value="Greetings"/>
        <setting name="path" value="C:\Libraries\cpp"/>
        <setting name="include" value="Greetings.h"/>
        <setting name="source" value="Greetings.cpp"/>
     </implementation>
  </implementations>
<!-- ... -->

 

Über die Einstellungen in den einzelnen <implementation>-Elementen kann der generierte Code die jeweiligen in Java, C++ oder C# definierten Funktionen aufrufen. Eine .mff-Datei kann so geschrieben werden, dass sie für mehrere Programmiersprachen verwendet werden kann. In diesem Fall muss jede Sprache ein weiteres <implementation>-Element enthalten. Im Folgenden werden die Einstellungen für die einzelnen Programmiersprachen erläutert.

Java-Bibliotheksreferenz

 

<!-- ... -->
<implementation language="java">
  <setting name="package" value="com.hello.functions"/>
  <setting name="class" value="Greetings"/>
</implementation>
<!-- ... -->

 

Damit der generierte Code Ihre Greetings.class-Datei findet, stellen Sie sicher, dass zum Java Classpath eine Referenz zu Ihrer Klasse hinzugefügt wurde.

C#-Bibliotheksreferenz

 

<!-- ... -->
     <implementation language="cs">
        <setting name="namespace" value="MyLibrary" />
        <setting name="class" value="Greetings" />
        <setting name="reference" value="C:\Libraries\cs\MyLibrary\bin\debug\MyLibrary.dll" />
     </implementation>
<!-- ... -->

 

Es ist in C# wichtig, dass der Namespace im Code dem in der .mff-Datei definierten Namespace entspricht (im Codefragment oben ist der Namespace MyLibrary). Dasselbe gilt für den Klassennamen (im Codefragment oben ist der Klassenname Greetings). Die dritte Einstellung, reference, gibt den Pfad der mit dem generierten Code zu verknüpfenden dll-Datei an.

C++-Bibliotheksreferenz

 

<!-- ... -->
  <implementation language="cpp">
        <setting name="namespace" value="MyLibrary"/>
        <setting name="class" value="Greetings"/>
        <setting name="path" value="C:\Libraries\cpp"/>
        <setting name="include" value="Greetings.h"/>
        <setting name="source" value="Greetings.cpp"/>
  </implementation>
<!-- ... -->

 

Beachten Sie folgende Anmerkungen zu C++:

 

namespace ist der Namespace, in dem Ihre Greetings-Klasse definiert wird. Er muss mit dem Attribut library im Element mapping übereinstimmen.

path ist der Pfad, unter dem die include- und die Quelldatei zu finden sind.

Wenn Code für ein Mapping generiert wird, werden die include- und die Quelldatei in das Verzeichnis targetdir/libraryname kopiert, das durch Auswahl der Menüoption Datei | Code generieren in | C++ definiert wird, und in die Projektdatei inkludiert.

 

Alle bereitgestellten include-Dateien werden in den generierten Algorithmus inkludiert.

 

Schritt 3. Hinzufügen einer Komponente

Im Bibliotheksfenster wird jede Funktion unter einer Funktionsgruppe angezeigt, z.B. "string functions". In der .mff-Datei entspricht eine Funktion einem <component>-Element. Umgekehrt muss sich jedes <component>-Element unter einem <group>-Element befinden, z.B.:

 

<!-- ... -->
<group name="string functions">
  <component name="sayhello">
  <!-- ... -->
  </component>
</group>
<!-- ... -->

 

Im unten stehenden Code ist eine Beispielfunktion (component) namens sayhellodefiniert.

 

<!-- ... -->
<component name="sayhello">
  <sources>
     <datapoint name="ismorning" type="xs:boolean"/>
  </sources>
  <targets>
     <datapoint name="result" type="xs:string"/>
  </targets>
  <implementations>
  <!-- ... -->
  </implementations>
  <description>
    <short>result = sayhello(ismorning)</short>
    <long>Returns "Good morning" or "Good day", depending on the input parameter.</long>
  </description>
</component>
<!-- ... -->

 

So würde die Komponente in MapForce angezeigt werden:

mf_custom_func

Ein <datapoint>-Element im obigen Codefragment ist sozusagen der Eingabe- oder Ausgabeparameter einer Funktion (auch als Input- oder Output-Konnektor bezeichnet). Das Argument type des <datapoint>-Elements definiert den Datentyp des Parameters oder den Datentyp des Rückgabewerts. Für jede Funktion kann nur ein Ziel-Datenpunkt definiert werden. Sie können jedoch beliebig viele Quell-Datenpunkte definieren.

 

Beim Datentyp für die einzelnen Datenpunkte muss es sich um einen der XML-Schematypen handeln (z.B. xs:string, xs:integer, usw.). Diese Datentypen müssen den Datentypen der Funktionsparameter, die Sie in Ihrer Java-, C++- oder C#-Bibliothek definiert haben, entsprechen. Informationen zum Mapping von XML-Schema-Datentypen auf Sprachtypen finden Sie unter Datentyp-Zuordnung.

 

Funktionen sind im Bibliotheksfenster durch kurze und lange Beschreibungen ergänzt. Die Kurzbeschreibung wird immer rechts neben dem Funktionsnamen angezeigt, während die lange Beschreibung als Tooltip zu sehen ist, wenn Sie den Mauszeiger über die Kurzbeschreibung halten (siehe Abbildung unten).

mf_custom_func_description_zoom70

 

Schritt 4. Definieren von Sprachimplementierungen

Wir können nun die Funktion im Fenster Bibliotheken mit der Funktion in der benutzerdefinierten Java-, C#- oder C++-Klasse verbinden. Dies wird über das Element <implementation> bewerkstelligt. Eine einzige Funktion kann mehrere <implementation>-Elemente haben - eines für jede unterstützte Programmiersprache. Eine Funktion kann in Java den Namen Hello oder in C++ den Namen SayHello haben. Aus diesem Grund müssen Sie für jede Programmiersprache einen eigenen Funktionsnamen definieren. Eine Funktion für jede einzelne der drei Programmiersprachen kann folgendermaßen aussehen.

 

<!-- ... -->
<component name="sayhello">
<!-- ... -->
  <implementations>
     <implementation language="cs">
        <function name="HelloFunction"/>
     </implementation>
     <implementation language="java">
        <function name="Hello"/>
     </implementation>
     <implementation language="cpp">
        <function name="SayHello"/>
     </implementation>
  </implementations>
<!-- ... -->
</component>
<!-- ... -->

 

Der als Funktionsname bereitgestellte Wert muss mit dem Namen der Methode in der Java-, C#- oder C++-Klasse übereinstimmen.

 

© 2018-2024 Altova GmbH