Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   XML (https://www.delphipraxis.net/46-xml/)
-   -   Delphi Probleme mit wohlgeformte-XML-Datei (https://www.delphipraxis.net/46524-probleme-mit-wohlgeformte-xml-datei.html)

toko 26. Mai 2005 14:04


Probleme mit wohlgeformte-XML-Datei
 
Hallo,

ich benutze eine XML-Datei um CD-Listen abzuspeichern. Den Dateinamen können die Benutzer selber wählen.
Also für eine CD-Listen eine XML-Datei.
Ich habe folgende Prozedur zum Anlegen einer XML-Datei:
Delphi-Quellcode:
procedure TfrmMain.createNewXMLFile;
var
  NewXMLDoc : TXMLDocument;
  xmlInitializeContents : TStrings;
begin
  NewXMLDoc := TXMLDocument.Create(self);
  xmlInitializeContents := TStringList.Create;
  xmlInitializeContents.Add('<?xml version="1.0"?>');
  xmlInitializeContents.Add('<!DOCTYPE ?Name_weiß_ich_nicht? "?Name_weiß_ich_nicht?.dtd">');
  xmlInitializeContents.Add('<cdorganizer>');
  xmlInitializeContents.Add('</cdorganizer>');
  NewXMLDoc.XML := xmlInitializeContents;
  NewXMLDoc.Active := true;
  if dlgSave.Execute then begin
    NewXMLDoc.FileName := dlgSave.FileName;
    NewXMLDoc.SaveToFile(NewXMLDoc.FileName);
  end;
  NewXMLDoc.Active := true;
end;
Damit die XML-Datei wohlgeformt ist, muss doch folgende Zeile eingefügt werden, oder?
Delphi-Quellcode:
  xmlInitializeContents.Add('<!DOCTYPE ?Name_weiß_ich_nicht? "?Name_weiß_ich_nicht?.dtd">');
hier habe ich aber das Problem, dass ich nicht weiß, welche Datei der Benutzer später im SaveDialog angibt, um so die dtd-Datei zu erstellen.

Liege ich den damit richtig? Denn wenn ich den "Doctype" weglasse sieht meine xml-Datei so aus:
XML-Code:
<?xml version="1.0"?>
<cdorganizer>
   <cd><cdid>1</cdid><cdtitel>test</cdtitel><interpret>test</interpret><genre>test</genre></cd><cd></cdorganizer>
Die CD-Elemente lege ich folgendermaßen an:
Delphi-Quellcode:
procedure TfrmCD.btnOKClick(Sender: TObject);
var
  cdobj: TCD;
  newsub,
  newcd : IXMLDOMNode;
begin
  cdobj := TCD.Create;
  cdobj.CDTitel := edtTitel.Text;
  cdobj.CDInterpret := edtInterpret.Text;
  cdobj.CDGenre := edtGenre.Text;
  cdobj.Save;
  {in XML-Datei schreiben, anfang}
  newcd := frmMain.xmlDoc.createElement('cd');

  newsub := frmMain.xmlDoc.createElement('cdid');
  newsub.text := IntToStr(frmMain.strgrdCDListe.RowCount);
  newcd.appendChild(newsub);

  newsub := frmMain.xmlDoc.createElement('cdtitel');
  newsub.text := cdobj.CDTitel;
  newcd.appendChild(newsub);

  newsub := frmMain.xmlDoc.createElement('interpret');
  newsub.text := cdobj.CDInterpret;
  newcd.appendChild(newsub);

  newsub := frmMain.xmlDoc.createElement('genre');
  newsub.text := cdobj.CDGenre;
  newcd.appendChild(newsub);

  frmMain.xmlDoc.documentElement.appendChild(newcd);
  frmMain.xmlDoc.save(frmMain.xmlfile);
  {in XML-Datei schreiben, ende}
 
  {in TStringGrid zu Ansicht darstellen}
  with frmMain.strgrdCDListe do begin
    begin
      RowCount := frmMain.strgrdCDListe.RowCount+1;
      Cells[0,frmMain.strgrdCDListe.RowCount-1]:=IntToStr(frmMain.strgrdCDListe.RowCount-1);
      Cells[1,frmMain.strgrdCDListe.RowCount-1] := cdobj.CDTitel;
      Cells[2,frmMain.strgrdCDListe.RowCount-1] := cdobj.CDInterpret;
      Cells[3,frmMain.strgrdCDListe.RowCount-1] := cdobj.CDGenre;
      RowHeights[frmMain.strgrdCDListe.RowCount-1] := rowxheights;
    end;
  end;
  cdobj.Free;
  Close;
end;
Ich habe nämlich vor im nachhinen nach einer "cd" über die cd-id zu suchen und weitere Kindknoten an diesem Eintrag anhängen.
Z.B. soll die Datei dann folgendermaßen aussehen:
XML-Code:
<?xml version="1.0"?>
<cdorganizer>
    <cd>
        <cdid>1</cdid>
        <cdtitel>titel 1</cdtitel>
        <interpret>interpret 1</interpret>
        <genre>genre 1</genre>
        <track>
            <trackid>1</trackid>
            <tracktitel>track 1</tracktitel>
            <dauer>3:11:07</dauer>
        </track>
        <track>
            ...
        </track>
    </cd>
    <cd>
        ...
    </cd>
</cdorganizer>
Über Hilfe bin ich sehr dankbar. :cry: Kritik zum Code ist ebenfalls willkommen.

gruß

MathiasSimmack 26. Mai 2005 14:29

Re: Probleme mit wohlgeformte-XML-Datei
 
Wohlgeformtheit hat nichts mit einem Doctype zu tun. Der Doctype bzw. das Hier im Forum suchenXSD-Schema definiert nur, wie die Datei aufgebaut ist, so dass der Parser ggf. Alarm schlägt, wenn der Inhalt nicht den Erwartungen entspricht.

Bei dieser XML-Komponente von Delphi gab´s irgendeinen "Indent"-Parameter. Den musst du nutzen, damit diese von dir gewünschte Formatierung zu sehen ist. An sich ist es aber unerheblich, denn Wohlgeformtheit bedeutet, dass es keine offenen Knoten gibt, und dass jeder öffnende Knoten ein schließendes Gegenstück hat, usw. Also sind sowohl
XML-Code:
<Test>
  <Hallo>
    <Welt/>
  </Hallo>
</Test>
als auch
XML-Code:
<Test><Hallo><Welt/></Hallo></Test>
wohlgeformt.

XML-Code:
<Test><HalloWelt/><test>
wäre es dagegen nicht, weil sich die Schreibweise des schließenden </test> von der des öffnenden <Test> unterscheidet.

toko 26. Mai 2005 15:47

Re: Probleme mit wohlgeformte-XML-Datei
 
Hallo,

Danke, für die schelle Antwort.
ich benutze die MSXML-Komponente. Gibt es da auch den Indent-Parameter? Es kann auch sein, dass ich mit den XML-Komponenten durcheinander gekommen bin.

Das XML-Document ist auf jeden Fall vom folgenden Typ:
Delphi-Quellcode:
    xmlDoc: IXMLDOMDocument2;
Als "uses" habe ich folgende angegeben:
xmldom, XMLIntf, msxmldom, XMLDoc, MSXML2_TLB;

gruß

toko 26. Mai 2005 16:04

Re: Probleme mit wohlgeformte-XML-Datei
 
Hallo,

eine Frage kommt noch dazu. Wie kann ich bei der obigen XML-Datei ermitteln, wieviel tracks es zu einem cd-Knoten gibt?
Oder kann ich die "cdid" usw. als Attribut dem Element "cd" zuweisen.

In der Art:
XML-Code:
<cd id=1 cdtitel=Titel 1 cdinterpret=Interpret 1 cdgenre= Genre 1>
    <track>
            <trackid>1</trackid>
            <tracktitel>track 1</tracktitel>
            <dauer>3:11:07</dauer>
    </track>
</cd>
Der Hintergrund ist der, dass ich die CDs in einem TStringgrid darstelle. Wenn ich auf diesem TStringgrid eine CD markiert habe, dann sollen in einem zweiten TStringgrid die Tracks dieser einen CD angzeigt werden.

Die Darstellung der CDs im ersten TStringgrid klappt.

vielen Dank...

MathiasSimmack 26. Mai 2005 19:38

Re: Probleme mit wohlgeformte-XML-Datei
 
Zitat:

Zitat von toko
ich benutze die MSXML-Komponente. Gibt es da auch den Indent-Parameter?

AFAIK nicht. Das müsstest du selbst programmieren, oder du findest dich damit ab, dass die XML-Datei ein wenig merkwürdig aussieht. Ich habe mir für eine Klasse zwei Funktionen geschrieben:
Delphi-Quellcode:
procedure THelp2Export.SetIndent(const RootNode: IXMLDOMNode; Level: integer);

  function CloneChar(const charSign: char; const Amount: integer): string;
  var
    i : integer;
  begin
    for i := 1 to Amount do
      Result := Result + charSign;
  end;

var
  lBreak : IXMLDOMText;
begin
  if(FXmlDoc <> nil) then
  try
    lBreak := FXmlDoc.createTextNode(widestring(CloneChar(#9,Level)));
    RootNode.appendChild(lBreak);
  except
  end;
end;

procedure THelp2Export.SetLineBreak(const RootNode: IXMLDOMNode);
var
  lBreak : IXMLDOMText;
begin
  if(FXmlDoc <> nil) then
  try
    lBreak := FXmlDoc.createTextNode(#13#10);
    RootNode.appendChild(lBreak);
  except
  end;
end;
die ich bspw. so aufrufe:
Delphi-Quellcode:
self.SetIndent(RootNode,1);
RootNode.appendChild(NewNode);
self.SetLineBreak(NewNode);

Zitat:

Wie kann ich bei der obigen XML-Datei ermitteln, wieviel tracks es zu einem cd-Knoten gibt?
Per Hier im Forum suchenXPath und Hier im Forum suchenselectNodes am einfachsten. Du musst nur den passenden Pfad angeben. Ist <cd> dein oberster Knoten? Dann könnte das so aussehen:
Delphi-Quellcode:
nodes := xmlDoc.selectNodes('/cd[id="1"]/track');
Aber dazu würde ich dir, neben den Fundstücken im Forum, die XML-Doku von Microsoft empfehlen.

toko 27. Mai 2005 10:39

Re: Probleme mit wohlgeformte-XML-Datei
 
Danke.

Zitat:

Ist <cd> dein oberster Knoten? Dann könnte das so aussehen:
mein oberster Knoten ist <cdorganizer> mit den Kindknoten <cd>, dann wieder mit den Kindknoten <track>, also:
Delphi-Quellcode:
<?xml version="1.0"?>
<cdorganizer>
    <cd>
        <cdid>1</cdid>
        <cdtitel>titel 1</cdtitel>
        <interpret>interpret 1</interpret>
        <genre>genre 1</genre>
        <track>
            <trackid>1</trackid>
            <tracktitel>track 1</tracktitel>
            <dauer>3:11:07</dauer>
        </track>
        <track>
            ...
        </track>
        ...
    </cd>
    <cd>
        ...
    </cd>
    ...
</cdorganizer>
ist meine vorgehensweise denn so sinnvoll?

Gruß

MathiasSimmack 27. Mai 2005 10:48

Re: Probleme mit wohlgeformte-XML-Datei
 
Inwiefern? :gruebel: Du musst und wirst doch bei der Arbeit mit der Datei bemerkt haben, ob dein Format gut durchdacht ist, oder ob man etwas verbessern könnte. Das kann ich, als Außenstehender, schlecht beurteilen.

Um auf das XPath zurückzukommen: Sieh den Aufbau der XML-Datei, bzw. die Anordnung der Knoten, wie den Aufbau eines Laufwerks. Sozusagen:
Code:
<C>
  <Programme>
    <Mozilla Firefox/>
  </Programme>
</C>
Um auf den <Mozilla Firefox>-Knoten zuzugreifen, wäre die XPath-Anfrage also
Delphi-Quellcode:
xmldoc.selectSingleNode('/C/Programme/Mozilla Firefox')
Der Slash vor dem C ist nur wichtig, wenn du direkt mit dem xmlDoc-Interface auf Knoten zugreifst. Wenn der genaue Pfad egal ist, bspw. um alle Links aus einer Datei zu ermitteln, dann tut´s auch ein
Delphi-Quellcode:
xmldoc.selectNodes('//a')
Aber so was steht alles in der XML-Doku von Microsoft.

toko 27. Mai 2005 11:48

Re: Probleme mit wohlgeformte-XML-Datei
 
OK, das hab ich in der Doku gerade auch gesehen. Ich schau die mir dann noch mal genauer an. Vielleicht werde ich da ja fündig. Falls nicht, komme ich mit spezielleren Fragen zurück.

Also, besten Dank nochmal...

Gruß


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:07 Uhr.

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