Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   XML (https://www.delphipraxis.net/46-xml/)
-   -   Delphi CreateNode mit mehreren Namespace-Angaben? (https://www.delphipraxis.net/168872-createnode-mit-mehreren-namespace-angaben.html)

TheHuette 15. Jun 2012 09:01

CreateNode mit mehreren Namespace-Angaben?
 
Hallo zusammen,

ich bin gerade dabei eine XML-Datei schreiben zu lassen, dessen komplizierte Inhalte hinsichtlich Namespaces meine noch sehr jungen XML-Kenntnisse überfordern und habe mittlerweile das Gefühl, dass ich mit Recherche nicht weiter komme, sondern mich an Experten wenden muss.

Mein Ziel ist es diesen Inhalt zu schreiben:

Code:
<?xml version="1.0" encoding="ISO-8859-15"?>
<DatenTeil>
        <Nutzdatenblock>
            <NutzdatenHeader version="10">
                <NutzdatenTicket>0001</NutzdatenTicket>
                <Empfaenger id="F">5117</Empfaenger>
                <Hersteller>
                    <ProduktName>xyz</ProduktName>
                    <ProduktVersion>VX.Y</ProduktVersion>
                </Hersteller>
                <DatenLieferant>Datenlieferant als String</DatenLieferant>
            </NutzdatenHeader>
            <Nutzdaten>
                <ebilanz:EBilanz version="000001" xmlns:ebilanz="http://rzf.fin-nrw.de/RMS/EBilanz/2009/XMLSchema">
                    <ebilanz:stichtag>20121231</ebilanz:stichtag>
                    <xbrli:xbrl
                            xmlns:de-gcd="http://www.xbrl.de/taxonomies/de-gcd-2011-09-14"
                            xmlns:link="http://www.xbrl.org/2003/linkbase"
                            xmlns:de-gaap-ci="http://www.xbrl.de/taxonomies/de-gaap-ci-2011-09-14"
                            xmlns:hgbref="http://www.xbrl.de/2006/ref"
                            xmlns:ref="http://www.xbrl.org/2004/ref"
                            xmlns:xbrldi="http://xbrl.org/2006/xbrldi"
                            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                            xmlns:xbrli="http://www.xbrl.org/2003/instance"
                            xmlns:iso4217="http://www.xbrl.org/2003/iso4217"
                            xmlns:xlink="http://www.w3.org/1999/xlink">
                        <link:schemaRef xlink:type="simple" xlink:href="http://www.xbrl.de/taxonomies/de-gcd-2011-09-14/de-gcd-2011-09-14-shell.xsd"/>
                        <link:schemaRef xlink:type="simple" xlink:href="http://www.xbrl.de/taxonomies/de-gaap-ci-2011-09-14/de-gaap-ci-2011-09-14-shell-fiscal.xsd"/>
Bis inklusive Zeile 15 (<ebilanz:stichtag>...) ist alles mit IXMLDOMDocument3 einfach machbar, aber dann weiß ich nicht, wie ich MSXML beibringen kann, dass es den Knoten "xbrli:xbrl" mit mehr als einer Namespace-Angabe definiert. Der Funktion createNode kann ich ja nur einen Namespace übergeben und der Versuch die Namespace-Angaben als Attribute schreiben zu lassen, endet bei mir in der Exception "Versuch, einen schreibgeschützten Knoten zu ändern." bzw. klingt für mich (wenn überhaupt) auch eher nach "dirty trick".

Die eigentliche Schwierigkeit sind dann die beiden Knoten "link:schemaRef". Der Name des Knoten befindet sich im Namespace "link", aber die Attribute im Namespace "xlink", daher denke ich dass die Namespaces alle schon vor dem Knoten "link:schemaRef" definiert sein müssen, eben im Knoten "xbrli:xbrl", der ja aber, so weit ich es sehe, schon voll damit beschäftigt ist seinen eigenen Namespace "xbrli" im CreateNode zu definieren.

Code:
[...]

  cNamespace_ebilanz = 'http://rzf.fin-nrw.de/RMS/EBilanz/2009/XMLSchema';
  cNamespace_de_gcd = 'http://www.xbrl.de/taxonomies/de-gcd-2011-09-14';
  cNamespace_link = 'http://www.xbrl.org/2003/linkbase';
  cNamespace_de_gaap_ci = 'http://www.xbrl.de/taxonomies/de-gaap-ci-2011-09-14';
  cNamespace_hgbref = 'http://www.xbrl.de/2006/ref';
  cNamespace_ref = 'http://www.xbrl.org/2004/ref';
  cNamespace_xbrldi = 'http://xbrl.org/2006/xbrldi';
  cNamespace_xsi = 'http://www.w3.org/2001/XMLSchema-instance';
  cNamespace_xbrli = 'http://www.xbrl.org/2003/instance';
  cNamespace_iso4217 = 'http://www.xbrl.org/2003/iso4217';
  cNamespace_xlink = 'http://www.w3.org/1999/xlink';
 
[...]
 
   function _AddChildNode(AXMLDoc: IXMLDOMDocument3; AParentNode: IXMLDOMNode;
    const AName: string; AAttributeNames: array of string;
    AAttributeValues: array of string; AText: string = ''; ANamespace: string = ''): IXMLDOMNode;
  var
    I: integer;
  begin
    Result := AParentNode.appendChild(AXMLDoc.createNode(NODE_ELEMENT, AName, ANamespace));

    if AText <> '' then
      Result.text := AText;

    if Length(AAttributeNames) <> Length(AAttributeValues) then
      Exit;

    for I := 0 to High(AAttributeNames) do
    begin
      Result.attributes.setNamedItem(AXMLDoc.createAttribute(AAttributeNames[I]));
      Result.attributes.getNamedItem(AAttributeNames[I]).text := AAttributeValues[I];
    end;
  end;
 
[...]

xml := CoDOMDocument60.Create();
xml.SetProperty('SelectionLanguage','XPath');
xml.SetProperty('SelectionNamespaces',
    Format('xmlns:ebilanz="%s" xmlns:de-gcd="%s" xmlns:link="%s" xmlns:xlink="%s" '+
    'xmlns:de-gaap-ci="%s" xmlns:hgbref="%s" xmlns:ref="%s" xmlns:xbrldi="%s" ' +
    'xmlns:xsi="%s" xmlns:xbrli="%s" xmlns:iso4217="%s"'
    ,[cNamespace_ebilanz, cNamespace_de_gcd, cNamespace_link, cNamespace_xlink,
    cNamespace_de_gaap_ci, cNamespace_hgbref, cNamespace_ref, cNamespace_xbrldi,
    cNamespace_xsi, cNamespace_xbrli, cNamespace_iso4217]));
 
xml.documentElement := xml.createElement('DatenTeil');

[...]                

Node := _AddChildNode(xml, Node, 'ebilanz:EBilanz', ['version'], ['000001'], '', cNamespace_ebilanz);

//hier Knoten "xbrli:xbrl" inklusive aller Namespaces schreiben, aber wie?
Über sachdienliche Hinweise wäre ich sehr dankbar! :-)

Freundliche Grüße
Martin v.H.

shmia 15. Jun 2012 10:34

AW: CreateNode mit mehreren Namespace-Angaben?
 
Diese Namespace-Angaben sind nichts anderes als Attribute:
Delphi-Quellcode:
// element erzeugen
element := document.createNode(NODE_ELEMENT, {elementname=}'xbrl', {namespace=}'xbrli') as IXMLDOMElement;
element.setAttribute('xmlns:de-gcd', 'http://www.xbrl.de/taxonomies/de-gcd-2011-09-14');
element.setAttribute('xmlns:link', 'http://www.xbrl.org/2003/linkbase');
...
// und unter dem Parent einhängen
parent.appendChild(element);
PS:
Ich habe dein Problem nicht gründlich genug gelesen,
aber bei Attributen ist es so, dass sie keinem Namespace angehören.
Man muss also nur:
Delphi-Quellcode:
element.setAttribute('xlink:href', 'http://www.xbrl.de/taxonomies/de-gcd-2011-09-14/de-gcd-2011-09-14-shell.xsd);

TheHuette 15. Jun 2012 13:44

AW: CreateNode mit mehreren Namespace-Angaben?
 
Jawoll, so klappt das. Danke!

Das Problem war meine merkwürdige Zuweisung der Attribute...
Code:
Result.attributes.setNamedItem(AXMLDoc.createAttribute(AAttributeNames[I]));
Result.attributes.getNamedItem(AAttributeNames[I]).text := AAttributeValues[I];
Result war vom Typ IXMLDOMNode. Wenn ich IXMLDOMElement statt IXMLDOMNode verwende, kann ich ähnlich deinem Beispiel
Code:
Result.setAttribute(AAttributeNames[I], AAttributeValues[I]);
aufrufen und bekomme die Meldung hinsichtlich schreibgeschütztem Knoten nicht mehr.

:thumb:


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:11 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz