Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   XML (https://www.delphipraxis.net/46-xml/)
-   -   Delphi XML: Namespace - Zuweisung funktioniert nicht (https://www.delphipraxis.net/69882-xml-namespace-zuweisung-funktioniert-nicht.html)

s-off 21. Mai 2006 19:57


XML: Namespace - Zuweisung funktioniert nicht
 
Hallo zusammen,

folgendes:

ich habe eine XML-Datei nach folgendem Schema:

XML-Code:
<?xml version="1.0" encoding="UTF-8"?>
<inputx xmlns="http://einszweidrei.de">
<document>
   <ordner>
      <name>Ordner1</name>
         <datei>
            <name>Datei1</name>
            <groesse>Groesse1</groesse>
            <attribut>Attribut1</attribut>
         </datei>
         <ordner>
            <name>Ordner2</name>
               <datei>
                  <name>Datei2</name>
                  <groesse>Groesse2</groesse>
                  <attribut>Attribut2</attribut>
               </datei>
               <datei>
                  <name>Datei3</name>
                  <groesse>Groesse3</groesse>
                  <attribut>Attribut3</attribut>
               </datei>
               <datei>
                  <name>Datei4</name>
                  <groesse>Groesse4</groesse>
                  <attribut>Attribut4</attribut>
               </datei>
               <ordner>
                  <name>Ordner3</name>
                     <datei>
                        <name>Datei2</name>
                        <groesse>Groesse2</groesse>
                        <attribut>Attribut2</attribut>
                     </datei>
                     <datei>
                        <name>Datei3</name>
                        <groesse>Groesse3</groesse>
                        <attribut>Attribut3</attribut>
                     </datei>
                     <datei>
                        <name>Datei4</name>
                        <groesse>Groesse4</groesse>
                        <attribut>Attribut4</attribut>
                     </datei>
               </ordner>
         </ordner>
   </ordner>
</document>
</inputx>
Ich möchte nun die einzelnen Ordner in eine TreeView-Komponente einlesen.
Das funktioniert auch super, wenn ich den Namespace vorher aus der Datei entferne.

Lasse ich den Namespace in der Datei, und weise ihn folgendermaßen zu, funktioniert das auslesen nicht mehr:

Delphi-Quellcode:
      xmlDoc.Load(sXMLFileName);
      xmlDoc.SetProperty('SelectionNamespaces','xmlns:na="http://einszweidrei.de"');
Die Ordner versuche ich nun, so einzulesen und in den TreeView zu schreiben, da ich das mit dem voranstellen von 'na:' hier im Forum gefunden habe:

Delphi-Quellcode:
procedure TfrmMain.ShowFolders(Node: IXMLDOMElement; nParent: PVirtualNode);
var
   i: Integer;
   nlFolders: IXMLDOMNodeList;
   nName, nChild: IXMLDOMElement;
   TreeData: TTreeData;
begin
   ChangeCursor;
   tvTree.BeginUpdate;
   try
      tvTree.NodeDataSize := SizeOf(TTreeData);
      nlFolders := Node.selectNodes('na:Folder');
      for i := 0 to Pred(nlFolders.length) do
      begin
         nChild := nlFolders.item[i] as IXMLDomElement;
         nName := nChild.selectSingleNode('na:name') as IXMLDOMElement;
         TreeData.Caption := nName.text;
         TreeData.Node := nChild;
         ShowFolders(nChild, AddVSTStructure(nParent, TreeData, nChild));
      end;
   finally
      tvTree.EndUpdate;
      ChangeCursor;
   end;
end;
Tja, nur leider funktioniert das so nicht - nl.Folders.length bleibt 0 und der TreeView leer :o(

MathiasSimmack 21. Mai 2006 20:32

Re: XML: Namespace - Zuweisung funktioniert nicht
 
Klar, weil die Unterknoten keinen eigenen Namespace besitzen.

s-off 21. Mai 2006 21:05

Re: XML: Namespace - Zuweisung funktioniert nicht
 
Hallo,

und was bedeutet das?

Ich kann die Datei auch nicht einlesen, wenn ich das 'na:' vor den zu suchenden Nodes weglasse.
Lösche ich aber den Namespace aus der XML-Datei, so funktioniert das Einlesen problemlos.

Ich habe das hier in mehreren Beiträgen gelesen, wo die gleiche Ausgangssituation bestand, beispielsweise hier:

Delphipraxis

oder hier:

Delphipraxis

MathiasSimmack 21. Mai 2006 21:19

Re: XML: Namespace - Zuweisung funktioniert nicht
 
Eins vorweg: Mein Fehler, :oops:, du kannst dir die ganze Arbeit sparen. Zweitens: die Situation ist nicht identisch, weil die gezeigten Beispiele davon ausgingen, dass einzelne Knoten einer XML-Datei unterschiedliche Namespaces haben. In deinem Fall gibt es nur einen, der im Root-Knoten deklariert wird. Daher kannst du auf den ganzen "SelectionNamespaces"-Quatsch verzichten und gleich per XPath die gewünschten Knoten abgreifen. Der Beweis:
Delphi-Quellcode:
var
  xmldoc : DomDocument;
  node  : IXMLDOMNode;
begin
  xmldoc := CoDomDocument.Create;
  if xmldoc <> nil then
  try
    xmldoc.load('bla.xml');
    node := xmldoc.selectSingleNode('/inputx/document/ordner/ordner');
    ShowMessage (node.xml);
  finally
    xmldoc := nil;
  end;
end;
zeigt den XML-Knoten des Ordners "Ordner2". :stupid:

s-off 21. Mai 2006 22:01

Re: XML: Namespace - Zuweisung funktioniert nicht
 
Hallo,

das funktioniert leider auch nicht *verzweifel*

Also, ich lese die Datei folgendermaßen ein:

Delphi-Quellcode:
procedure TfrmMain.toolbarButtons_btnOpenFileClick(Sender: TObject);
var
   Node: IXMLDOMElement;
begin
   if OpenDialog1.Execute then
   begin
      xmlDoc := CoDomDocument40.Create;
      xmlDoc.async := False;

      sXMLFileName := OpenDialog1.FileName;

      xmlDoc.Load(sXMLFileName);

      ClearTreeView(tvTree);
      Node := xmlDoc.selectSingleNode('/inputx/document') as IXMLDOMElement; <- hier habe ich schon zig Varianten getestet
      ShowFolders(Node, nil); <- hier übergebe ich Node an ShowFolders
      oStatusBar1.Panels[0].Caption := sXMLFileName;
   end;
end;
Dann rufe ich die Prozedur ShowFolders auf und übergebe die Node:

Delphi-Quellcode:
procedure TfrmMain.ShowFolders(Node: IXMLDOMElement; nParent: PVirtualNode);
var
   i: Integer;
   nlFolders: IXMLDOMNodeList;
   nName, nChild: IXMLDOMElement;
   TreeData: TTreeData;
begin
   ChangeCursor;
   tvTree.BeginUpdate;
   try
      tvTree.NodeDataSize := SizeOf(TTreeData);
      nlFolders := Node.selectNodes('Folder');
      for i := 0 to Pred(nlFolders.length) do
      begin
         nChild := nlFolders.item[i] as IXMLDomElement;
         nName := nChild.selectSingleNode('name') as IXMLDOMElement;
         TreeData.Caption := nName.text;
         TreeData.Node := nChild;
         ShowFolders(nChild, AddVSTStructure(nParent, TreeData, nChild));
      end;
   finally
      tvTree.EndUpdate;
      ChangeCursor;
   end;
end;
Das Problem ist aber, dass in der ersten Prozedur die Variable Node schon Nil bleibt.
Node := xmlDoc.selectSingleNode('/inputx/document') as IXMLDOMElement; findet also nichts :(

Hier noch die Funktion, mit der ich dann den TreeView fülle:

Delphi-Quellcode:
function TfrmMain.AddVSTStructure(ANode: PVirtualNode; ARecord: TTreeData; nNode: IXMLDOMElement): PVirtualNode;
var
   Data: PTreeData;
begin
   Result := tvTree.AddChild(ANode);
   Data := tvTree.GetNodeData(Result);
   tvTree.ValidateNode(Result, False);
   Data^.Caption := ARecord.Caption;
   Data^.Node := nNode;
   Data^.ImageIndex := 1;
end;
Ich öle schon den ganzen Tag daran herum, aber es will und will nicht funktionieren :(
Wäre lieb, wenn sich nochmal jemand erbarmen würde :?

marabu 22. Mai 2006 05:40

Re: XML: Namespace - Zuweisung funktioniert nicht
 
Guten Morgen Sascha.

Wenn ich mir die Testdaten im Beitrag #1 anschaue, dann frage ich mich, warum ein perfektes root element (document) nochmal in ein Element verpackt wird, nur um einen default namespace zu vergeben. Da du im Verlauf des threads noch mit dem Alias na experimentierst, scheint der namespace keine Vorgabe zu sein - oder?

Am Beispiel deiner Testdaten dokumentiert der default namespace eigentlich nur, zu welcher tag library dein markup gehört. Das erlaubt eine Validierung sogar bei gleichzeitig vorhandener Namensüberdeckung, die du aber nicht hast, da nur eine tag library verwendet wird.

Für deinen Code ändert sich da gar nichts. Der Zugriff über XPath bleibt derselbe, bis auf das versenkte root element "document". An deinem Programmcode sieht man, dass du mit anderem markup als dem gezeigten testest. Mag sein, dass in deinem Code die Selektion des Startelements für ShowFolder fehlschlägt. In meinem Code mit deinem markup aus Beitrag #1 gibt es keine Probleme.

Grüße vom marabu

s-off 22. Mai 2006 07:19

Re: XML: Namespace - Zuweisung funktioniert nicht
 
Hallo marabu,

der Namespace steht genau so (nur mit anderer URL) in meiner XML-Datei.
Korrekt, der Inhalt der XML-Datei ist nicht exakt der, den ich in Beitrag #1 gepostet habe - aber die gleiche Struktur.

Ich werde das gleich noch einmal ausprobieren - ohne document.

Danke.

MathiasSimmack 22. Mai 2006 07:47

Re: XML: Namespace - Zuweisung funktioniert nicht
 
Zitat:

Zitat von s-off
das funktioniert leider auch nicht *verzweifel*

Es ist immer wieder lustig, solche Sachen lesen zu müssen, nachdem man getesteten Code postet. Nun ja, ich sage mal, du machst definitiv etwas falsch. Ich habe nur zwei Zeilen aus deinem Code genommen und die Anzeige des XML-Codes per "ShowMessage" ergänzt:
Delphi-Quellcode:
      xmlDoc.Load('bla.xml');
Node := xmlDoc.selectSingleNode('/inputx/document') as IXMLDOMElement;
ShowMessage(Node.xml);
Voilà, die Dialogbox zeigt mir den XML-Code ab <document> an. Das bedeutet also, "Node" ist nicht nil, und der Code macht exakt das, was man von ihm erwartet. Dass ich den Dateinamen fest angegeben habe, und dass ich auch "ClearTreeView" nicht verwendet habe, dürfte hier zu vernachlässigen sein.

Guck mal in deine "ShowFolders"-Prozedur
Zitat:

Delphi-Quellcode:
nlFolders := Node.selectNodes('na:Folder');

Denk mal darüber nach. Oder falls das zu subtil war: Wo in deiner XML-Datei befindet sich denn ein Knoten mit dem Namen <Folder>? Ich bin der Meinung, es könnte damit zu tun haben, dass dein Baum leer bleibt. :roll:



Warnung: Dieser Beitrag könnte verletzenden Sarkasmus enthalten.

s-off 22. Mai 2006 08:35

Re: XML: Namespace - Zuweisung funktioniert nicht
 
Hallo Mathias,

mit Deinem 'verletzenden' Sarkasmus kann ich gut umgehen :wink:

Vielleicht erläutere ich mal ganz kurz die Situationh, in der ich mich augenblicklich befinde.
Bis vor einer Woche habe ich mich weder mit dem Thema XML, noch mit dem Thema VirtualTreeView, noch mit dem Thema Pointern auseinandersetzen müssen.
Jetzt muss es leider sein, und die XML-Datei, mit der ich zu tun habe, sowie der VirtualTreeView von Mike Lischke sind dabei Vorgabe.

Wenn ich bei Google das Stichwort 'XML' oder 'XPath' eingebe, dann gibt es kaum noch Seiten, die nicht als 'bereits besucht' gekennzeichnet werden. Es ist also nicht so, dass ich mich auf meinen Hintern setze, und andere machen lasse.

Es ist nur so, dass hier drei Themen auf mich stürzen, mit denen ich - ich möchte nicht sagen, dass ich überfordert bin - aber die mir schon einige Kopfschmerzen bereiten.

Wenn Du das Thema auf Anhieb verstanden hast, als Du anfingst, Dich damit zu beschäftigen, dann finde ich das schön - geh aber bitte nicht davon aus, dass es jedem so leicht fällt, sich in neue Dinge innerhalb kürzester Zeit einzuarbeiten.

So, nun zu Deiner Antwort:

Zitat:

Es ist immer wieder lustig, solche Sachen lesen zu müssen, nachdem man getesteten Code postet.
Die von Dir geposteten Codezeilen werden sicherlich funktionieren - aber in meinen Funktionen / Prozeduren funktioniert es, wie ich oben versucht habe deutlich zu machen, nicht.

Zitat:

Nun ja, ich sage mal, du machst definitiv etwas falsch.
Ich gehe ganz stark davon aus, dass ich irgendeine grundlegende Sache noch nicht verstanden habe - ja.

Zitat:

Ich habe nur zwei Zeilen aus deinem Code genommen und die Anzeige des XML-Codes per "ShowMessage" ergänzt:
Delphi-Quellcode: markieren
xmlDoc.Load('bla.xml');
Node := xmlDoc.selectSingleNode('/inputx/document') as IXMLDOMElement;
ShowMessage(Node.xml);

Voilà, die Dialogbox zeigt mir den XML-Code ab <document> an. Das bedeutet also, "Node" ist nicht nil, und der Code macht exakt das, was man von ihm erwartet. Dass ich den Dateinamen fest angegeben habe, und dass ich auch "ClearTreeView" nicht verwendet habe, dürfte hier zu vernachlässigen sein.
Wie bereits gesagt, sollte das so, wie es dort steht, funktionieren. Nagel mich jetzt bitte nicht darauf fest, dass ich sagte
Zitat:

s-off hat folgendes geschrieben:
das funktioniert leider auch nicht *verzweifel*
Das war schlicht und einfach auf meinen Code mit Deinem Vorgehen bezogen.

Zitat:

Denk mal darüber nach. Oder falls das zu subtil war: Wo in deiner XML-Datei befindet sich denn ein Knoten mit dem Namen <Folder>? Ich bin der Meinung, es könnte damit zu tun haben, dass dein Baum leer bleibt.
Wie in meinem letzten Beitrag bereits erwähnt, entspricht die gepostete XML-Datei inhaltlich nicht dem Original - strukturell dennoch schon.

So, ich probiere es nun nochmal mit den Anmerkungen von marabu - sprich ohne document - sollte das auch nicht funktionieren, dann bettel ich wieder um Hilfe :wink:

marabu 22. Mai 2006 08:54

Re: XML: Namespace - Zuweisung funktioniert nicht
 
Hallo Sascha,


nur damit du dich nicht verrennst:

Zitat:

Zitat von marabu
Der Zugriff über XPath bleibt derselbe, bis auf das versenkte root element "document"

Damit wollte ich nur ausdrücken, dass durch die Einführung des tags "inputx" das ursprüngliche root element "document" (um bei den tagnames aus deinem Beispiel zu bleiben) um eine Ebene weiter nach unten versetzt wurde und dadurch der XPath Ausdruck nicht "/document" sondern "/inputx/document" sein muss - wie du es ja selbst richtig erkannt hast. In meinem Beispiel-Code (Demo mit ShowFolder) mache ich glaube ich gar keine Query, weil das root element über die Methode documentElement() verfügbar ist.

Noch ein Tip: es ist nicht gut, wenn du in einem Projekt gleich mehrere persönliche Forschungsgebiete angehst. Du kommst am schnellsten zum Ziel, wenn du zuerst ein Demo-Projekt zum Umgang mit allen Aspekten von Zeigern erstellst. Das Einarbeiten in VST und XML würde ich getrennt angehen. Erst wenn du dich im Umgang mit den einzelnen Techniken vertraut fühlst, solltest du deine eigentliche Anwendung ins Auge fassen.

Freundliche Grüße vom marabu

s-off 22. Mai 2006 09:32

Re: XML: Namespace - Zuweisung funktioniert nicht
 
Hallo marabu,

Zitat:

Damit wollte ich nur ausdrücken, dass durch die Einführung des tags "inputx" das ursprüngliche root element "document" (um bei den tagnames aus deinem Beispiel zu bleiben) um eine Ebene weiter nach unten versetzt wurde und dadurch der XPath Ausdruck nicht "/document" sondern "/inputx/document" sein muss - wie du es ja selbst richtig erkannt hast.
hmm, damit wäre ich ja wieder da, wo ich gestern auch schon war - denn mit '/inputx/document' hatte ich es ja bereits vergeblich versucht :?

Zitat:

Noch ein Tip: es ist nicht gut, wenn du in einem Projekt gleich mehrere persönliche Forschungsgebiete angehst.
Das habe ich auch schon gemerkt :wink:
Nur leider kann man es sich oftmals nicht aussuchen, gerade dann, wenn einem die Zeit im Nacken sitzt. Aber in diesem Fall war es wohl tatsächlich eine absolute Fehlentscheidung :( Wahrscheinlich wäre ich wirklich schneller gewesen, wenn ich erst alle Themen in kleinen Beispielprojekten durchgegangen wäre :?

Nun ja, dann tüftel ich jetzt mal noch ein bissel mit '/inputx/document' herum.

Da aber Node := xmlDoc.selectSingleNode('/inputx/document') as IXMLDOMElement schon Nil geblieben ist, wird das wahrscheinlich wieder ein heilloses Unterfangen :|

Trotzdem danke, dass Ihr Euch so bemüht :wink:

MathiasSimmack 22. Mai 2006 09:38

Re: XML: Namespace - Zuweisung funktioniert nicht
 
Zitat:

Zitat von s-off
Wenn Du das Thema auf Anhieb verstanden hast, als Du anfingst, Dich damit zu beschäftigen, dann finde ich das schön - geh aber bitte nicht davon aus, dass es jedem so leicht fällt, sich in neue Dinge innerhalb kürzester Zeit einzuarbeiten.

Ist sicher eine Frage des Interesses. Ich habe mit Begeisterung die entsprechenden Kapitel im Platform SDK gelesen und viel experimentiert. Dafür gibt es andere Themen, die mich weniger interessieren, und mit denen ich dann Schwierigkeiten hätte. :stupid:


Nun versteh mich bitte nicht falsch, aber was ist an deiner XML-Datei denn so "intern" oder "geheim" (in Ermangelung eines besseren Begriffs), dass du hier eine ähnlich strukturierte Datei postest, aber eben nicht das Original? Es sind manchmal Kleinigkeiten, die den Erfolg verhindern (Darsteller aus der P*rnobranche hören das oft :mrgreen:), und dazu gehört für mich eben, dass du einerseits die falsche Datei, aber den richtigen Code zeigst.

Komm schon, Chinesen sind doch gar nicht anwesend ... :zwinker:

s-off 22. Mai 2006 10:00

Re: XML: Namespace - Zuweisung funktioniert nicht
 
Hehe :wink:

Geheimes steht da nicht drin - es ist nur so, dass die Datei gut 14 MB groß ist.
Daher habe ich das Ganze etwas verkürzt nachgestellt.

marabu 22. Mai 2006 10:10

Re: XML: Namespace - Zuweisung funktioniert nicht
 
Bei dieser Dateigröße brauchst du schon gute Argumente dafür, dass du die ganze Datei als DOM-Dokument im Hauptspeicher hältst. Schau dir mal den Speicherverbrauch im Taskmanager an. Eventuell ist ja SAX eine bessere Lösung für dein Problem.

marabu

s-off 22. Mai 2006 10:20

Re: XML: Namespace - Zuweisung funktioniert nicht
 
Au Backe - daran habe ich gar nicht gedacht.

Und ist mir ehrlich gesagt auch gar nicht unangenehm aufgefallen - hmm, bei 2GB wohl auch kein Wunder :?

Werde mir dieses SAX dann wohl auch mal zu Gemüte führen müssen.

*Wuaaaaaaaaaa*heul*

Danke für den Hinweis - das hätte derbe ins Auge gehen können :roll:

s-off 22. Mai 2006 11:10

Re: XML: Namespace - Zuweisung funktioniert nicht
 
Tjo,

habe nun wohl alle möglichen Kombinationen ausprobiert:

Delphi-Quellcode:
RootNode := xmlDoc.selectSingleNode('inputx');
RootNode := xmlDoc.selectSingleNode('/inputx');
RootNode := xmlDoc.selectSingleNode('//inputx');

RootNode := xmlDoc.selectSingleNode('inputx/document');
RootNode := xmlDoc.selectSingleNode('/inputx/document');
RootNode := xmlDoc.selectSingleNode('//inputx/document');

RootNode := xmlDoc.documentElement.selectSingleNode('inputx');
RootNode := xmlDoc.documentElement.selectSingleNode('/inputx');
RootNode := xmlDoc.documentElement.selectSingleNode('//inputx');

RootNode := xmlDoc.documentElement.selectSingleNode('inputx/document');
RootNode := xmlDoc.documentElement.selectSingleNode('/inputx/document');
RootNode := xmlDoc.documentElement.selectSingleNode('//inputx/document');
Ich denke mal, mehrere Möglichkeiten gibt es nicht mehr - RootNode ist jedenfalls immer NIL :|

Ich gebe es auf und lege den ganzen Kram ad acta - keine Lust mehr....

Vielen Dank trotzdem nochmal für Eure Unterstützung. Ihr konntet mir das Thema XML ein wenig näher bringen, auch wenn es für den finalen Erfolg nicht genügt hat - was aber wohl aus meiner eigenen Schusseligkeit resultiert. Vielleicht bin ich auch nicht offen genug, mich 100% auf das Thema einzulasssen - ich weiss es nicht.

Einen positiven Nebeneffekt hat das Ganze jedoch gehabt - ich weiss nun endlich den VirtualTreeView grundlegend zu bedienen :stupid:

marabu 22. Mai 2006 11:21

Re: XML: Namespace - Zuweisung funktioniert nicht
 
Sascha, es müssten doch schon die ersten 5 Zeilen deiner Originaldaten reichen um dein Problem nachzustellen - oder?

marabu

s-off 22. Mai 2006 11:56

Re: XML: Namespace - Zuweisung funktioniert nicht
 
Okidoki, hier der Anfang der besagten XML-Datei:

XML-Code:
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://earth.google.com/kml/2.0">
<Document>
   <Folder>
      <name>My Places</name>
       <open>1</open>
       <Folder>
         <name>Ordner1</name>
         <open>1</open>
         <Placemark>
              <name>Placemark1</name>
              <LookAt>
                <longitude>10.37993318693747</longitude>
                <latitude>19.35357660723419</latitude>
                <range>743945.2733547823</range>
                <tilt>-1.858292979523515e-013</tilt>
                <heading>1.206473994247129</heading>
              </LookAt>
              <styleUrl>root://styleMaps#default+nicon=0x307+hicon=0x317</styleUrl>
              <Point>
                <coordinates>10.37993318693747,19.35357660723419,0</coordinates>
              </Point>
         </Placemark>

MathiasSimmack 22. Mai 2006 12:14

Re: XML: Namespace - Zuweisung funktioniert nicht
 
Code:
/kml/Document/Folder
für den obersten. Schreibweise beachten! XML legt Wert auf korrekte Groß- und Kleinschreibung der Knotennamen. So ist <Document> eben nicht <document>, usw.

s-off 22. Mai 2006 13:15

Re: XML: Namespace - Zuweisung funktioniert nicht
 
Also,

Du glaubst es jetzt wahrscheinlich nicht, aber

Delphi-Quellcode:
procedure TfrmMain.toolbarButtons_btnOpenFileClick(Sender: TObject);
var
   nlist: ixmldomnodelist;
   Node: IXMLDOMElement;
begin
   if OpenDialog1.Execute then
   begin
      xmlDoc := CoDomDocument40.Create;
      xmlDoc.async := False;
      sXMLFileName := OpenDialog1.FileName;
      xmlDoc.Load(sXMLFileName);
      Node := xmlDoc.documentElement.selectSingleNode('/kml/Document/Folder') as IXMLDOMElement;
      //Node := xmlDoc.selectSingleNode('/kml/Document/Folder') as IXMLDOMElement;
      showmessage(node.text);
      oStatusBar1.Panels[0].Caption := sXMLFileName;
   end;
end;
funktioniert nicht :gruebel: :wall:

s14 22. Mai 2006 13:30

Re: XML: Namespace - Zuweisung funktioniert nicht
 
s-off,
ich habe mal die Knoten einer XML-Datei so ausgewertet:

Delphi-Quellcode:
function XMLGetSoftwareItems: TSoftwareItems;
// Gibt eine Liste der zu installierenden Software und deren Status
// für die grafische Aufbereitung zurück.
var
  XMLColl : IXMLDOMDocument2;
  XMLNodes : IXMLDOMNodeList;
  XMLNode : IXMLDOMNode;
  i, err  : Integer;
  s       : String;
begin


  XMLColl := CoDOMDocument30.Create;
  XMLColl.load( XMLFilename );

  err := XMLColl.parseError.errorCode;
  if err = 0 then
  begin
    XMLNodes := XMLColl.documentElement.selectNodes('setup');
    for i := 0 to XMLNodes.length -1 do
    begin
      XMLNode := XMLNodes.item[i];

      SetLength(Result, XMLNodes.length);

      Result[i].Status := StrToInstStatus(XMLNode.selectSingleNode('InstStatus').text);

      Result[i].Text := XMLNode.selectSingleNode('name').text;

      Result[i].ID := StrToIntDef(XMLNode.selectSingleNode('id').text, 0);

    end;
  end else
  begin
    Log(Format('In "XMLGetSoftwareItems" ist die Analyse der XML-Datei "%s" ist fehlgeschlagen:', [XMLFilename]), etError);
    Log(Format(' %s', [XMLColl.parseError.reason]));
  end;
end;
Das muss natürlich von Dir angepasst werden. Ich wollte nur die Funktionsweise aufzeigen. :-)

Gruß

marabu 22. Mai 2006 13:37

Re: XML: Namespace - Zuweisung funktioniert nicht
 
Sascha, probiere es mal so:

Delphi-Quellcode:
... xmlDoc.selectSingleNode('/kml/Document/Folder') ...
marabu

s-off 22. Mai 2006 13:49

Re: XML: Namespace - Zuweisung funktioniert nicht
 
Funktioniert leider auch nicht:

Delphi-Quellcode:
procedure TfrmMain.toolbarButtons_btnOpenFileClick(Sender: TObject);
var
   Node: IXMLDOMNode;
begin
   if OpenDialog1.Execute then
   begin
      xmlDoc := CoDomDocument40.Create;
      xmlDoc.async := False;

      sXMLFileName := OpenDialog1.FileName;

      xmlDoc.Load(sXMLFileName);

      Node := xmlDoc.selectSingleNode('/kml/Document/Folder'); //<-- Node bleibt NIL

      showmessage(node.text);
   end;
end;

s14 22. Mai 2006 13:58

Re: XML: Namespace - Zuweisung funktioniert nicht
 
Also, wenn ich das richtig sehe sind in der Datei mehrere Knoten mit dem Namen "Folder" in der selben Ebene.
Du musst zuerst eine NodeList auf '/kml/Document/Folder' setzen und dann mit
einer SingleNode "NodeList[i]" darauf zugreifen um alle "Folder" zu durchlaufen.

Warum hast Du bei meinem Beispiel die NodeList ignoriert? ;-)

s-off 22. Mai 2006 14:05

Re: XML: Namespace - Zuweisung funktioniert nicht
 
Hallo s14, ich habe eine NodeList, die ich Element für Element durchgehe ->

Delphi-Quellcode:
procedure TfrmMain.ShowFolders(Node: IXMLDOMElement; nParent: PVirtualNode);
var
   i: Integer;
   nlFolders: IXMLDOMNodeList;
   nName, nChild: IXMLDOMElement;
   TreeData: TTreeData;
begin
   ChangeCursor;
   tvTree.BeginUpdate;
   try
      tvTree.NodeDataSize := SizeOf(TTreeData);
      nlFolders := Node.selectNodes('Folder');
      for i := 0 to Pred(nlFolders.length) do
      begin
         nChild := nlFolders.item[i] as IXMLDomElement;
         nName := nChild.selectSingleNode('name') as IXMLDOMElement;
         TreeData.Caption := nName.text;
         TreeData.Node := nChild;
         ShowFolders(nChild, AddVSTStructure(nParent, TreeData, nChild));
      end;
   finally
      tvTree.EndUpdate;
      ChangeCursor;
   end;
end;
Ausgangspunkt ist hier Node, welche aus 'toolbarButtons_btnOpenFileClick' (siehe Vorbeitrag) kommt.
Wenn Du Dir meine vorherigen Beiträge anschaust, wirst Du sehen, dass ich diesbezüglich schon viel herumexperimentiert habe :wink:

marabu 22. Mai 2006 15:21

Re: XML: Namespace - Zuweisung funktioniert nicht
 
Hallo Sascha,

der angegebene XPath ist jetzt korrekt für den aktuellen Kontext. Wenn trotzdem das Ergebnis nil ist, dann ist der Knoten "Folder" nicht der einzige Knoten mit diesem Namen. Du musst dann noch ein identifizierendes Merkmal mit aufnehmen, damit der Zugriff eindeutig wird.

marabu

Neuromancer 22. Mai 2006 15:58

Re: XML: Namespace - Zuweisung funktioniert nicht
 
Zitat:

Zitat von s-off
XML-Code:
<kml xmlns="http://earth.google.com/kml/2.0">

Vorsicht, ich glaube, hier liegt der casus cnactus...

Du deklarierst hier einen sogenannten "Empty Namespace", und das mag der M$-XML-Parser überhaupt nicht. (Irgendwo im msdn steht das auch, dass er das nicht mag...)

Aber ein wenig Workaround schafft Abhilfe:

Delphi-Quellcode:
aXMLDOMDoc.setProperty('NewParser', true);
aXMLDOMDoc.setProperty('SelectionLanguage', 'XPath');
aXMLDOMDoc.setProperty('SelectionNamespaces', 'xmlns:ENS="http://earth.google.com/kml/2.0"'); // Den empty ns (=ENS) dem Parser mitteilen.
der entsprechende XPath-Befehl sieht dann so aus:
Delphi-Quellcode:
    aXMLDOMDoc.selectSingleNode('/ENS:Knoten1/ENS:Knoten2/ENS:Knoten3...usw.');
Gruß

marabu 22. Mai 2006 16:09

Re: XML: Namespace - Zuweisung funktioniert nicht
 
Hallo Armin,

hier liegt ein default namespace vor - kein empty namespace.

Grüße vom marabu

Neuromancer 22. Mai 2006 16:16

Re: XML: Namespace - Zuweisung funktioniert nicht
 
Zitat:

Zitat von marabu
Hallo Armin,

hier liegt ein default namespace vor - kein empty namespace.

Grüße vom marabu

Ähm, entschuldige, ich meinte natürlich einen default namespace... :oops:

Ändert aber nichts an der Tatsache, dass der M$-XML-Parser damit nicht umgehen kann.

Ich habe jetzt nicht genau die Stelle im msdn gefunden, in der es geschrieben steht, aber dafür folgendes:

Zitat:

Zitat von msdn
However, using default namespaces instead of utilizing explicitly mapped prefixes for element names can be confusing because it is not obvious that the elements in the document are namespace scoped.

Gruß

marabu 22. Mai 2006 16:29

Re: XML: Namespace - Zuweisung funktioniert nicht
 
Was wäre wenn du dich irren würdest? Nicht auszudenken - die Verwirrung bei den Lesern, welche weniger davon verstehen als ich und du. Kannst du es nicht einfach schnell mal ausprobieren? Die nötigen Testdaten stehen im PSDK oder auch der MSDN Online Library. Du musst auch kein Programm zum Testen schreiben. Nimm einfach MSXSL.EXE dazu.

Freundliche Grüße vom marabu

s-off 22. Mai 2006 16:37

Re: XML: Namespace - Zuweisung funktioniert nicht
 
Hallo marabu,

Zitat:

der angegebene XPath ist jetzt korrekt für den aktuellen Kontext. Wenn trotzdem das Ergebnis nil ist, dann ist der Knoten "Folder" nicht der einzige Knoten mit diesem Namen. Du musst dann noch ein identifizierendes Merkmal mit aufnehmen, damit der Zugriff eindeutig wird.
Das war ja jetzt nur ein Test, um zu schauen, ob da überhaupt etwas gefunden wird, was bei näherer Betrachtung, wie Du schon richtig sagst, ja gar nicht funktionieren kann. Eigentlich müsste es für meinen Fall ja folgendermaßen lauten: 'Node := xmlDoc.selectSingleNode('/kml/Document');' damit ich den Ausgangspunkt, ab dem gesucht werden soll, und der vorher 'xmlDoc.documentElement' war, wieder korrekt setze.
Das funktioniert aber leider auch nicht. Und 'Node := xmlDoc.selectSingleNode('/kml/Document/*');' ebenso wenig.
Ziel ist es ja, alle Folder-Elemente - deren name-Eigenschaft ich ja nicht kenne - anzusprechen, ausgehend von einem bestimmten Punkt.

Bisher - also ohne den Namespace in der XML-Datei - war dieser Ausgangspunkt ja 'xmlDoc.documentElement'.

Diesen Übergebe ich ja an die Funktion 'ShowFolders' als IXMLDomElement.

In dieser möchte ich ja dann mittels 'nlFolders := Node.selectNodes('Folder');' alle Folder-Elemente abgreifen, und in den TreeView schreiben.
Das kann doch nicht sein, dass diese eine blöde Zeile da in der Datei all das kaputt macht, was vorher so schön funktioniert hat :(

Neuromancer 22. Mai 2006 16:41

Re: XML: Namespace - Zuweisung funktioniert nicht
 
Zitat:

Zitat von marabu
Was wäre wenn du dich irren würdest? Nicht auszudenken - die Verwirrung bei den Lesern, welche weniger davon verstehen als ich und du.

Nichts liegt mir ferner als dieses, ehrlich...

Ich kann nur aus Erfahrung sprechen. Und diese hat gezeigt, dass der Parser eben nicht mit Default Namespaces umgehen kann (ich habe eben gesucht, aber ich finde die Stelle im msdn nicht mehr, die ich meine...sry)

Wie wäre es denn, wenn Sascha selbst mal schnell den Code umbauen würde? Er sieht ja dann gleich, ob es dann klappt oder nicht.
Oder er nimmt alternativ die Deklaration des Default namespace heraus, dann müsste es eigentlich auch funktionieren.

Auch wenn es arrogant klingt: aber ich schließe aus, dass ich mich (in diesem Fall) irre.

Denn ich habe mit diesem "Fehler" auch schon genügend zu kämpfen gehabt. Sobald man dem Parser allerdings ein wenig "Nachhilfe" gibt, kommt er gut damit zurecht.

Gruß

s-off 22. Mai 2006 16:45

Re: XML: Namespace - Zuweisung funktioniert nicht
 
Zitat:

However, using default namespaces instead of utilizing explicitly mapped prefixes for element names can be confusing because it is not obvious that the elements in the document are namespace scoped.
Wenn das stimmt, dann platzt mir der Arsch :freak: *sorry* :wink:

Aber dadurch sehe ich ein klitzekleines Lichtlein am Ende des Tunnels und werde das gleich mal ausprobieren :thumb:

Neuromancer 22. Mai 2006 16:47

Re: XML: Namespace - Zuweisung funktioniert nicht
 
Ich habe nochmal gesucht, und das hier gefunden:

Zitat:

Zitat von msdn
However, XPath treats the empty prefix as the null namespace. In other words, only prefixes mapped to namespaces can be used in XPath queries. If you want to use the default namespace from an XML document in the XPath expression, then you need to define a prefix for it.

Ist zwar immer noch nicht das, was ich gemeint habe, aber ich hoffe, das bringt uns weiter...


Ich suche aber nochmal...

Gruß

marabu 22. Mai 2006 16:57

Re: XML: Namespace - Zuweisung funktioniert nicht
 
Hallo Armin,

mag sein, dass der MSXML Parser das eine oder andere Problem hat - aber an der Stelle habe ich für diesen thread nie graben müssen, denn meine Demo-Anwendung verarbeitet die Daten von Sascha problemlos. Egal ob ich XPath verwende oder direkt über documentElement.firstChild() gehe.

Delphi-Quellcode:
procedure TDemoForm.FileOpenAccept(Sender: TObject);
var
  n: IXMLDOMNode;
begin
  with Sender as TFileOpen do
  begin
    doc := CoDomDocument.Create;
    doc.async := false;
    if doc.Load(Dialog.FileName) then
    begin
      StatusBar.SimpleText := Dialog.FileName;
      TreeNodes.Clear;
      n := doc.selectSingleNode('/kml/Document');
//    n := doc.documentElement.firstChild;
      ShowFolder(n as IXMLDOMElement, nil);
    end;
  end;
end;
Nachdenkliche Grüße vom marabu

Neuromancer 22. Mai 2006 17:08

Re: XML: Namespace - Zuweisung funktioniert nicht
 
Hallo Marabu,

ich sehe, unsere Definitionen der Variablen gehen auseinander...

Ich erzeuge für gewöhnlich das IXMLDOMDocument mit CoDomDocument40.Create.
Die Dokument-Variable ist dabei vom Typ "IXMLDOMDocument" oder "IXMLDOMDocument2".

Könntest du das mal bitte umschreiben und dann mit XPath testen? Möglicherweise ist dieser Bug / dieses Feature neu.

Danke und Gruß

Neuromancer 22. Mai 2006 17:33

Re: XML: Namespace - Zuweisung funktioniert nicht
 
So, ich habe es endlich gefunden...

Zitat:

Zitat von msdn
One other XPath enhancement that you can expect sometime soon has to do with proper namespace support. According to the XPath specification, when expressions contain unqualified element names (no namespace prefix), the elements are considered part of no namespace (even if a default namespace declaration is present in the source document). When XPath expressions contain qualified names (through a namespace prefix) they are evaluated according to the namespace bindings that make up the current XPath context. However, there is currently no mechanism in place for establishing namespace bindings prior to evaluating an XPath expression in MSXML 3.0. This makes it impossible to properly query namespace-aware XML documents.
For example, assuming the following XML document:

<foo xmlns='urn:foo-bar:baz'>
<bar><baz/></bar>
</foo>

what should be returned by the /foo/bar/baz expression? According to the XPath specification, it should return nothing because it's looking for foo, bar, and baz elements that belong to no namespace. But in the source document the foo, bar, and baz elements all belong to the urn:foo-bar:baz namespace.
To solve this problem, in a future release of MSXML 3.0 it will be possible to specify namespace bindings through the SelectionNamespaces property before calling selectNodes, as shown here:

doc.setProperty "SelectionNamespaces", _
"xmlns:f='urn:foo-bar:baz'"
set sel = doc.selectNodes("/f:foo/f:bar/f:baz")

With the namespace bindings in place, this expression should now behave properly because it identifies foo, bar, and baz elements that belong to the 'urn:foo-bar:baz', which matches the default namespace declaration in the source document. (Note that syntax may change by release time.)

In der Praxis ergibt sich daraus folgendes:

Ich habe Saschas xml-Datei mal so "validiert":
XML-Code:
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://earth.google.com/kml/2.0">
   <Document>
      <Folder>
         <name>My Places</name>
         <open>1</open>
         <Folder>
            <name>Ordner1</name>
            <open>1</open>
            <Placemark>
               <name>Placemark1</name>
               <LookAt>
                  <longitude>10.37993318693747</longitude>
                  <latitude>19.35357660723419</latitude>
                  <range>743945.2733547823</range>
                  <tilt>-1.858292979523515e-013</tilt>
                  <heading>1.206473994247129</heading>
               </LookAt>
               <styleUrl>root://styleMaps#default+nicon=0x307+h
icon=0x317</styleUrl>
               <Point>
                  <coordinates>10.37993318693747,19.35357660723419
,0</coordinates>
               </Point>
            </Placemark>
         </Folder>
      </Folder>
   </Document>
</kml>
Dann funktioniert folgender Code nicht:
Delphi-Quellcode:
procedure TForm1.btnGoClick(Sender: TObject);
var
  aXMLDoc: IXMLDOMDocument2;
  aXMLNode: IXMLDOMNode;
begin
  aXMLDoc := CoDOMDocument40.Create;
  aXMLDoc.setProperty('NewParser', true);
  aXMLDoc.setProperty('SelectionLanguage', 'XPath');

  if not aXMLDoc.loadXML(me1.Text) then
    raise Exception.Create('shyce war''s beim Laden des XML-Dokuments!');

  aXMLDoc.save('test.xml');

  aXMLNode := aXMLDoc.selectSingleNode('kml');

  if aXMLNode = nil then
     raise Exception.Create('kein Knoten gefunden!');

  ShowMessage(aXMLNode.xml);
end;
...und die Exception wird geworfen.

Bringe ich dem Parser aber bei, was M$ fordert, dann funktioniert der Code:

Delphi-Quellcode:
procedure TForm1.btnGoClick(Sender: TObject);
var
  aXMLDoc: IXMLDOMDocument2;
  aXMLNode: IXMLDOMNode;
begin
  aXMLDoc := CoDOMDocument40.Create;
  aXMLDoc.setProperty('NewParser', true);
  aXMLDoc.setProperty('SelectionLanguage', 'XPath');
  // !!!
  aXMLDoc.setProperty('SelectionNamespaces', 'xmlns:DNS="http://earth.google.com/kml/2.0"');

  if not aXMLDoc.loadXML(me1.Text) then
    raise Exception.Create('shyce war''s beim Laden des XML-Dokuments!');

  aXMLDoc.save('test.xml');

  aXMLNode := aXMLDoc.selectSingleNode('DNS:kml'); // !!!

  if aXMLNode = nil then
     raise Exception.Create('kein Knoten gefunden!');

  ShowMessage(aXMLNode.xml);
end;
Ich hoffe, ich habe jetzt nicht noch mehr Verwirrung, sondern Aufklärung gestiftet...;)

Gruß

Neuromancer 22. Mai 2006 17:42

Re: XML: Namespace - Zuweisung funktioniert nicht
 
Also, eben nachgeprüft:

Matthias und Marabu, dass euer Code funktioniert, liegt daran, dass ihr das Objekt mit CoDOMDocument.Create erzeugt. Mit dem "alten" Parser funktioniert das und man kann - wie Matthias treffend formulierte - auf den ganzen SelectionNamespaces-Quatsch verzichten.

Arbeitet man jedoch mit einer höheren Version (ich weiß jetzt nicht genau, ab welcher), dann funktioniert der Code nicht mehr.

Sascha und ich haben mit CoDOMDocument40.Create erzeugt. Dann muss der Parser über die Default Namespaces in Kenntnis gesetzt und die XPath-Query entsprechend manipuliert werden.

Ich hoffe, das Problem ist damit (endlich) aus der Welt...;)

Gruß

s-off 22. Mai 2006 18:24

Re: XML: Namespace - Zuweisung funktioniert nicht
 
Hey, das funktioniert ja super :hello: :hello: :hello: :hello: *freu*

Oh menno, wie zwei so kleine Zahlen doch so viel verändern können :gruebel:

Jetzt nur noch ein paar Kleinigkeiten *hoff* anpassen, und alles ist lecker - danke Euch :thumb:

Ich denke, dass das Problem ggf. noch andere Leute treffen kann, die ebenfalls den aktuellen Parser benutzen - vielleicht sollte man das Ganze daher in die Code-Bibliothek aufnehmen.

Wenn das Progrämmchen mal fertig ist, werdet Ihr unter den Credits erwähnt - ohne Euch hätte ich es nicht geschafft!!!

marabu 22. Mai 2006 18:52

Re: XML: Namespace - Zuweisung funktioniert nicht
 
Hallo Armin,

das hast du schön heraus gearbeitet - Danke dafür. Das Verhalten war von Microsoft bereits in den Help Files zu MSXML 3.0 dokumentiert und für eine spätere Version (4.0) angekündigt worden. Ich war bisher nur ein einziges mal drüber gestolpert - heute war das zweite und hoffentlich letzte Mal.

Freundliche Grüße

marabu


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:04 Uhr.
Seite 1 von 2  1 2      

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