Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   XML (https://www.delphipraxis.net/46-xml/)
-   -   Unterknoten ohne Namespace wird nicht gefunden (https://www.delphipraxis.net/206990-unterknoten-ohne-namespace-wird-nicht-gefunden.html)

Incocnito 15. Feb 2021 11:05

Unterknoten ohne Namespace wird nicht gefunden
 
Hi zusammen,

das Problem ist so verworren, dass ich nicht so recht weiß wonach ich suchen sollte,
daher bitte nicht böse sein, wenn es diese Frage so oder so ähnlich schon gab und ich
die nur nciht gefunden habe.

Nun zum Problem:
Ich habe aus einer XSD mit Delphi automatisch eine PAS-Datei erzeugen lassen.
Dort wird in der XML-Datei mit Namespaces gearbeitet.
Unterknoten sind allgemein definiert in einer anderen XSD ohne Namespace.
Bei folgendem Abschnitt bekomme ich nun Probleme:
Code:
<toller_namespace:Ansprechpartner>
  <Person>
    <Eine_ID>4711</Eine_ID>
    <Vorname>Max</Vorname>
    <Nachname>Mustermann</Nachname>
  </Person>
</toller_namespace:Ansprechpartner>
Delphi erzeugt eine Get-Funktion:
Delphi-Quellcode:
function TXMLAnsprechpartner.Get_Person: IXMLPerson;
begin
  Result := ChildNodes['Person'] as IXMLPerson;
end;
Ich bekomme auch ein Objekt zurück, aber "Vorname" ist beispielsweise leer.
Nun habe ich herausgefunden, wenn ich manuell den Knoten suche (ChildNodes - Get(index) - NodeName)
finde ich ihn und dort sind die Werte enthalten.
FindNode findet den Knoten nicht, da er sich nicht im "richtigen" Namespace befindet.
Mein Versuch den Knoten manuell zu suchen und
1) den direkt zuzuweisen oder
2) einen neuen Knoten erstellen und die Werte einzelnd übernehmen
sind beide gescheitert.
Nr. 1 ging nicht, da der Typ nicht passte. Nr. 2 ging nicht, da ich durch das hin und her schieben
wohl den Referenzzähler versaue und er dann beim späteren Zugriff auf Zugriffsverletzungen läuft
(zumindest denke ich, dass ich den Referenzzähler versaue).

Die Frage ist also: Gibt es für den Fall, dass Unterknoten keinen oder einen anderen
Namespace haben, eine Lösung in Delphi? Ist das ein Fehler des XSD-Parsers?
Hatte außer mir noch jemand mal solch ein Problem und wie habt ihr das dann gelöst?

Mit freundlichem Gruß
Incocnito

himitsu 15. Feb 2021 16:31

AW: Unterknoten ohne Namespace wird nicht gefunden
 
Gibt auch beim Zugriff auf den Knoten deinen tollen Namespace an, dann sollte es gehn.


Alternativ bei der XML-Klasse einen "kurzen" Namespace vorgeben und dann Diesen beim Aufruf verwenden.

Incocnito 16. Feb 2021 07:43

AW: Unterknoten ohne Namespace wird nicht gefunden
 
Hi,

ich steh' wohl auf'm Schlauch.
Wenn ich die Routine ersetze und aus
Delphi-Quellcode:
begin
  Result := ChildNodes['Person'] as IXMLPerson;
end;
wird
Delphi-Quellcode:
var
  node : IXmlNode;
begin
  node := ChildNodes.FindNode('Person', '');
  Result := node as IXMLPerson;
end;
..., sagt Delphi "Interface nicht unterstützt".
(node ist hierbei übrigens nicht nil.)

LG Incocnito

TiGü 16. Feb 2021 07:51

AW: Unterknoten ohne Namespace wird nicht gefunden
 
Delphi-Quellcode:
var
  node : IXmlNode;
begin
  node := ChildNodes.FindNode('Person', 'toller_namespace');
  Result := node as IXMLPerson;
end;
Ist es so besser? Gleich? Schlimmer?

WiPhi 16. Feb 2021 07:52

AW: Unterknoten ohne Namespace wird nicht gefunden
 
Das Problem ist, das Delphis XML Databinding nicht mit Namespaces umgehen kann. Ein entsprechender QC Eintrag existiert schon sehr lange:
https://quality.embarcadero.com/browse/RSP-18172

Deswegen hat sich MvRens von x²software ein Tool gebau, was in der Lage ist XSDs mit Namespaces in PAS-Dateien umzuwandeln und es freundlicherweise auf GitHub veröffentlicht. Ich habe noch ein paar Anpassungen vorgenommen, damit läuft es für uns:

https://github.com/MvRens/x2xmldatabinding

Vielleicht hilft dir das auch weiter.

Incocnito 16. Feb 2021 10:01

AW: Unterknoten ohne Namespace wird nicht gefunden
 
Hi Zusammen,

ja x2 macht das hier scheinbar besser.
Musste nur Jedi aus dem Source rauswerfen, da ich in der Firma kein Jedi installiert habe
(und auch nicht einfach installieren darf)
und die erzeugte PAS-Datei noch überarbeiten, da er mit Fehlermeldungen gekommen war.
Ich denke das liegt wohl daran, dass x2utils und die erzeugte Datei von der Version her nicht zusammen passten.
Datumsfelder sind nun tatsächlich vom Typ "DateTime" auch nice.
Es gibt noch viele Dinge die ich mir nun ansehen muss.

etwas ärgerlich, weil ich mit
Delphi-Quellcode:
var
  node : IXmlNode;
const
  sCurrNodeName = 'Person';
begin
  node := ChildNodes.FindNode(sCurrNodeName, '');
  if (node = nil) then
  begin
    node := InternalAddChild(nil, sCurrNodeName, '', -1);
    node.SetAttributeNS('ns', GetNamespaceURI(), NULL);
  end;
  Result := TXMLPerson.CreateHosted(node as TXmlNode);
end;
schon dicht dran war. Nur wenn der Knoten nicht vorhanden war hatte er einen leeren Namespace hinzugefügt.

Was ich nicht verstanden hatte: Es gibt in der erzeugten XML einen Standard-Namespace (finde den in der kompletten
PAS-Datei nicht, wo der gesetzt werden soll), der hier gesetzt werden muss.
Delphi-Quellcode:
var
  node : IXmlNode;
const
  sCurrNodeName = 'Person';
  sNamespaceURI = 'http://www.test.de/versteckter/namespace/v.1.1';
begin
  node := ChildNodes.FindNode(sCurrNodeName, sNamespaceURI);
  if (node = nil) then
  begin
    //node := InternalAddChild(nil, sCurrNodeName, sNamespaceURI, -1);
    node := AddChild(sCurrNodeName, sNamespaceURI);
  end;
  Result := TXMLPerson.CreateHosted(node as TXmlNode);
end;
Damit ginge es dann auch bei mir.

Danke für die Hilfe schonmal. Ich schau mal, ob ich das noch etwas anders schreiben kann.

LG Icocnito

WiPhi 17. Feb 2021 07:19

AW: Unterknoten ohne Namespace wird nicht gefunden
 
Zitat:

Zitat von Incocnito (Beitrag 1483102)
Hi Zusammen,

ja x2 macht das hier scheinbar besser.
Musste nur Jedi aus dem Source rauswerfen, da ich in der Firma kein Jedi installiert habe
(und auch nicht einfach installieren darf)

Dafür darfst du gerne einen PR machen, das war von mir damals ein Schnellschuss um andere Drittanbieter-Komponenten zu entfernen.
Ich hätte es gerne auch in Plain Delphi VCL :)

Zitat:

Zitat von Incocnito (Beitrag 1483102)
Was ich nicht verstanden hatte: Es gibt in der erzeugten XML einen Standard-Namespace (finde den in der kompletten
PAS-Datei nicht, wo der gesetzt werden soll), der hier gesetzt werden muss.
Delphi-Quellcode:
var
  node : IXmlNode;
const
  sCurrNodeName = 'Person';
  sNamespaceURI = 'http://www.test.de/versteckter/namespace/v.1.1';
begin
  node := ChildNodes.FindNode(sCurrNodeName, sNamespaceURI);
  if (node = nil) then
  begin
    //node := InternalAddChild(nil, sCurrNodeName, sNamespaceURI, -1);
    node := AddChild(sCurrNodeName, sNamespaceURI);
  end;
  Result := TXMLPerson.CreateHosted(node as TXmlNode);
end;
Damit ginge es dann auch bei mir.

Das müsste man sich im Detail anschauen, wie deine XSD(s) aussehen und wie die zu erwartende XML Datei auszusehen hat.
Ggf. stimmt auch das Schema nicht 100%ig. Aber ein bisschen Detailarbeit im Nachhinein hat man immer.

himitsu 17. Feb 2021 10:36

AW: Unterknoten ohne Namespace wird nicht gefunden
 
Mein letztes Mal mit Namespace war nicht im Delphi, sondern im FinalBuilder.
Ich weiß daher nicht welche Option/Property/Funktion an der XML-Kasse das ist.

Die XML sah quasi so aus. (war eigentlich eine DPROJ von Delphi)
Code:
<Ansprechpartner xmlns="eine_url">
  <Person>
    <Eine_ID>4711</Eine_ID>
    <Vorname>Max</Vorname>
    <Nachname>Mustermann</Nachname>
  </Person>
</Ansprechpartner>
In der XML-Klasse XML-Funktion hatte ich dort einen "Identifier prefix for default namespace" angeben müssen
und konnte dann via XPath
Delphi-Quellcode:
'/n:Person/n:Eine_ID'
auf einen Node zugreifen.
Ein 'n:Eine_ID' sollte so wohl auch bei ChildNodes/FindNode verwendbar sein.


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:52 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