Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   XML (https://www.delphipraxis.net/46-xml/)
-   -   Delphi MSXML: Nicht valide Nodes ignorieren (https://www.delphipraxis.net/127745-msxml-nicht-valide-nodes-ignorieren.html)

Mr_G 18. Jan 2009 11:06


MSXML: Nicht valide Nodes ignorieren
 
Hallo zusammen,
hier ist beschrieben wie man mittels MSXML sein XML-Dokument gegen ein XSD-Schema prüfen kann. Gibt es mit MSXML eine Möglichkeit die Teilstrukturen, die nicht den Vorgaben entsprechen herauszufiltern und mit dem Rest weiterzuarbeiten?
Gruß

Mr_G

Mr_G 20. Jan 2009 11:41

Re: MSXML: Nicht valide Nodes ignorieren
 
*push* :duck:

Alaitoc 28. Jan 2009 15:12

Re: MSXML: Nicht valide Nodes ignorieren
 
Hallöle,
nunja vll bastelste dir was aus den Angaben, die ParseError.Code, ParseError.SrcText und so weiter geben.
Genaueres kann ich dir leider zur Zeit auch nicht sagen...versuche mich selbst an dem MSXML und er lädt nicht falls die geladene Datei mit dem XSD Schema nicht 100% übereinstimmt.

Mr_G 28. Jan 2009 17:52

Re: MSXML: Nicht valide Nodes ignorieren
 
Nunja... ich hab auch schon übelegt ob ich das selber bastel aber derzeit glaube ich es ist in meinem Fall fast einfacher nicht mit XSD zu validieren sondern einfach bei Zugriffsfehlern den aktuellen Vorgang abzubrechen.
Sollte es eine einfache Lösung mit MSXML geben: Immer her damit...

Alaitoc 2. Feb 2009 14:57

Re: MSXML: Nicht valide Nodes ignorieren
 
Ich parse die XML-Datei bisher und breche den Vorgang bei einem Fehler ab, dann lade ich sie ohne Überprüfung
in mein Textfeld und markiere mit ParseError.Line die Zeile (benutzte dafür SynEdit) und gebe unten die ParseError.Reason aus...sodass man wenigstens weiß was an der XML-Datei falsch ist.

Nun habe ich allerdings das Problem das wenn ich ein Schema einbinde, der Namespace identisch mit dem aus der Datei sein muss...also...so ganz fehlerfrei funktioniert es bisher nicht...aber ich schau mal weiter...durchwühle schon die ganze Zeit die MSXML 4.0 SDK Dokumentation.

MfG Alaitoc

Mr_G 2. Feb 2009 17:21

Re: MSXML: Nicht valide Nodes ignorieren
 
So eine Ausgabe wäre bei mir eher nicht praktikabel, denn es geht um einen Dienst der die Daten ausliest. Ich denke ich werde das ohne XSD machen und evtl. auftretende Fehler abfangen, sodass ich zumindest die korrekten Nodes alle einlesen kann. Alternativ wäre ganz abzubrechen aber das gefällt mir eigentlich nicht so gut.

Alaitoc 3. Feb 2009 11:40

Re: MSXML: Nicht valide Nodes ignorieren
 
Nunja was vll. möglich wäre...bei DOMDocument60 also bei MSXML 6.0 kann man scheinbar die einzelnen Nodes validieren, gibt da eine Funktion wo man einen Knoten angibt und dann einen ParseError zurück kriegt.

MfG Alaitoc

Mr_G 3. Feb 2009 18:11

Re: MSXML: Nicht valide Nodes ignorieren
 
Das wäre natürlich eine interessante eine Alternative. Danke für den Tipp!

Alaitoc 4. Feb 2009 12:27

Re: MSXML: Nicht valide Nodes ignorieren
 
Nur was mir dabei aufgefallen ist, ich kann ein einmal hinzugefügtes Schema nichtmehr entfernen.
Da erscheint nur eine Exception "Keine Implementierung"...keine Ahnung ob das nur bei mir ist.+

Edit: Habe es mal gelöst, indem ich jedesmal die SchemaCollection neuerstelle...etwas unschön...aber scheinbar entstehen auch keine MemoryLeaks.

MfG Alaitoc

sirius 4. Feb 2009 13:10

Re: MSXML: Nicht valide Nodes ignorieren
 
Zitat:

Zitat von Alaitoc
aber scheinbar entstehen auch keine MemoryLeaks

Wie hast du das festegestellt?

Alaitoc 4. Feb 2009 14:16

Re: MSXML: Nicht valide Nodes ignorieren
 
Ich hab eine Unit die jeweils die MemoryLeaks (glaube MemCheck wars) ausgibt, wenn ich das Programm beende und dann hab ich nochmal ein wenig eine Schleife durchlaufen lassen.

Btw: Jemand ne Idee wie ich die Präfixe der Namespaces herausfinde? Also xmlns:xsi="" ?

MfG Alaitoc

sirius 4. Feb 2009 14:52

Re: MSXML: Nicht valide Nodes ignorieren
 
Zitat:

Zitat von Alaitoc
Ich hab eine Unit die jeweils die MemoryLeaks (glaube http://v.mahon.free.fr/pro/freeware/memcheck/ wars) ausgibt, wenn ich das Programm beende und dann hab ich nochmal ein wenig eine Schleife durchlaufen lassen.

Ich fragte nur, weil MemLeaks bei COM-Objekten können mit den handelsüblichen Memorychecks zu Delhpi nicht gefunden werden.

Alaitoc 4. Feb 2009 15:08

Re: MSXML: Nicht valide Nodes ignorieren
 
Hmhm gute Frage, die Frage ist wie sollte ich es sonst lösen?
Scheinbar fehlt die Remove Methode in der SchemaCollection ab MSXML 6.

Btw vll noch einige interessante Einstellungen für den Parser: MSXML Parser Einstellungen

Edit: Achja und naja sonst freigeben kann ich die SchemaCollection auch nicht mit FreeandNil(), also denke ich das dies nicht nötig ist...naja ich hoffe es.

sirius 5. Feb 2009 09:41

Re: MSXML: Nicht valide Nodes ignorieren
 
Zitat:

Zitat von Alaitoc
Hmhm gute Frage, die Frage ist wie sollte ich es sonst lösen?
Scheinbar fehlt die Remove Methode in der SchemaCollection ab MSXML 6.

Keine Ahnung. Ich wollte nur kurz warnen. Es kann trotzdem sein, dass es so funktioniert. Ich habe mich mit der 6er Version noch nie auseinandergesetzt.

Alaitoc 6. Feb 2009 09:30

Re: MSXML: Nicht valide Nodes ignorieren
 
Hm aber vll. mit der 5er? ^^
Ich versuche MultipleErrorMessage zu nutzen, jedoch habe ich ein Problem zwischen dem IXMLDOMParseError und IXMLDOMParseError2...sind halt zwei unterschiedliche Datentypen und naja ne Idee?

Edit:Also will beim Validieren halt dank der MultipleErrorMessage Einstellung alle Fehler auswerten...nur keine Ahnung ob das bei Delphi überhaupt geht.


Schonmal Danke

Mr_G 6. Feb 2009 14:29

Re: MSXML: Nicht valide Nodes ignorieren
 
Ich habs einfach mal ausprobiert:
Delphi-Quellcode:
procedure TForm.FormCreate(Sender: TObject);
var tmp: IXMLDOMDocument2;
    lst: IXMLDOMParseErrorCollection;
    i: Integer;
begin
  tmp := CoDOMDocument60.Create;
  tmp.setProperty('MultipleErrorMessages', true);
  tmp.loadXML('<root><a>[/b]</root>');

  Memo.Clear;
  lst := (tmp.parseError as IXMLDOMParseError2).allErrors;
  for i := 0 to lst.length - 1 do
  begin
    Memo.Lines.Add(lst.item[i].reason);
  end;
end;
Vielleicht hilft das weiter...

Alaitoc 6. Feb 2009 14:49

Re: MSXML: Nicht valide Nodes ignorieren
 
Naja das Problem ist, er speichert da nun nur einen Fehler hinein...auch wenn mehrere vorhanden sind :/
Oder...mache ich noch was falsch? *am Kopf kratz*

MfG Alaitoc

Mr_G 6. Feb 2009 17:45

Re: MSXML: Nicht valide Nodes ignorieren
 
Kannst du mal deine Routine, dein Test-Schema und deine Test-XML-Datei hochladen. Eigentlich sollte das funktionieren.

Alaitoc 9. Feb 2009 07:27

Re: MSXML: Nicht valide Nodes ignorieren
 
Naja ich hab einfach mal ne Form und ne Memo erstellt, dann deinen Code kopiert und dann halt noch einen Fehler eingebaut...wird trotzdem nur der Erste angezeigt.

MfG Alaitoc

Alaitoc 9. Feb 2009 09:50

Re: MSXML: Nicht valide Nodes ignorieren
 
Hm könnte es daran liegen, das ich Delphi 7 benutze? :gruebel:

Edit: Hrm Delphi 2009 klappt es auch nicht...irgendwie bin ich langsam am verzweifeln...

Alaitoc 9. Feb 2009 14:59

Re: MSXML: Nicht valide Nodes ignorieren
 
Endlich eine Art Durchbruch...MultipleErrors funktioniert scheinbar nur bei der Schemaüberprüfung, also

Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
var tmp: IXMLDOMDocument2;
    lst: IXMLDOMParseErrorCollection;
    schema : IXMLDOMSchemaCollection2;
    i: Integer;
begin
  Memo.Clear;
  tmp := CoDOMDocument60.Create;
  schema:=CoXMLSchemaCache60.Create;
  tmp.setProperty('MultipleErrorMessages', true);
  tmp.loadXML('<test><a></a>[b][/b]</test>');
  schema.add('','C:\xsd.xsd');
  tmp.schemas:=schema;

  lst := (tmp.validate as IXMLDOMParseError2).allErrors;
  for i := 0 to lst.length -1  do
  begin
    Memo.Lines.Add(lst.item[i].reason);
  end;
end;
Zitat:

Der Inhalt des Elements 'a' ist gemäß dem Inhaltsmodell des übergeordneten Elements 'XXXXX' nicht gültig.
Erwartet: XXXX1, XXXX2, XXXX3, XXXX4, XXXX5.

Das Element 'b' wird verwendet, aber es ist im DTD/Schema nicht deklariert .
Zwar in gewisser Weise keine gute Nachricht...aber naja...jetzt müsste ich mir nur irgendwas überlegen wie er nicht beim Überprüfen der Wohlgeformtheit der XML-Datei abbricht. Und so perfekt wirkt es auch noch nicht...hmhm

Falls wer einen Tipp hat, her damit!

MfG Alaitoc

PS: Schonmal Danke für die Mühen :>

Mr_G 9. Feb 2009 15:34

Re: MSXML: Nicht valide Nodes ignorieren
 
Zitat:

Zitat von Alaitoc
Endlich eine Art Durchbruch...MultipleErrors funktioniert scheinbar nur bei der Schemaüberprüfung,...

Daher meine Frage nach dem Schema...

Was dein allgemeines Problem angeht: Eine "echte" Möglichkeit wird es wohl nicht geben... man weiß ja nicht wo der Fehler liegt und kann daher wahrscheinlich auch kaum "defekte" Teile ausschließen.

Was meine Frage angeht: Hast du schonmal probiert die "nicht-validen" Nodes ausfindig zu machen und bei der Verarbeitung zu ignorieren?

Alaitoc 9. Feb 2009 15:46

Re: MSXML: Nicht valide Nodes ignorieren
 
Liste der Anhänge anzeigen (Anzahl: 1)
Bin grade in gewisser Weise dabei, der MSXML Parser lädt den Text immer von oben nach unten und von innen nach außen...also wie in der Grafik beschrieben:

1.C
2.B
3.A
4.C2
5.B2
6.A2
7.Test

In diesen Blöcken...also müsste ich mir theorethisch "nur" eine Funktion schreiben die dann diesen Text "löscht" und weiter validiert, bis halt der ganze Text "richtig" ist. Und dann die Fehler ausgibt und markiert, wenn dann der ganze Text keine XML Fehler hat wird er erst mit dem XSD Schema verglichen...
Ist halt nur das Problem das Gegenstück jeweils von der "Fehlerquelle" zu finden.
Hmhm werde mal schauen.

MfG Alaitoc

Mr_G 9. Feb 2009 15:52

Re: MSXML: Nicht valide Nodes ignorieren
 
Ja... wie gesagt... das Gegenstück... Es könnte sich ja z.B. auch um Schreibfehler bzw. Auslassungen handeln etc. pp.
Ich kann mich gerade nicht so intensiv damit beschäftigen aber ich freue mich, wenn du mich auf dem Laufenden hälst! :chat:

Alaitoc 9. Feb 2009 16:23

Re: MSXML: Nicht valide Nodes ignorieren
 
Hui...ist doch ziemlich kompliziert, sobald man mal bei einem Element ein / vergisst zum schließen...ich glaub das wird länger dauern mit der Planung *seufz*

Gibts zufällig irgendwo eine feste Dokumentation wie das in welcher Reihenfolge geprüft wird mit der Wohlgeformtheit?^^

Naja werde mich morgen erstmal daran setzen...vll ist es ja machbar mit den Informationen die mir der MSXML Parser liefert.

MfG Alaitoc

Alaitoc 11. Feb 2009 10:29

Re: MSXML: Nicht valide Nodes ignorieren
 
Hm naja eine Möglichkeit wäre nun den Text durchzugehen, jeweils den Text von < bis > zu speichern und immer hochzuzählen , bzw. bei </ > runterzuzählen und die Elemente damit zu nummerieren und zu sagen ob es ein Anfangs oder Endelement ist.

Beispiel:
1 2 3 4 3 4 3 2 1 0
<test><a><c></c><c></c></a></test>

Falls dann ein Fehler auftritt, sucht man vom Endelement aus das andere Element...indem man die Zahl des Endelements+1 sucht und überprüft ob es ein Anfangselement ist...theorethisch könnte man diese dann ganz leicht entfernen und dann wieder validieren...jedoch ist das nicht umbedingt effizient x)

MfG Alaitoc

himitsu 11. Feb 2009 10:34

Re: MSXML: Nicht valide Nodes ignorieren
 
Zitat:

Zitat von Alaitoc
Hm naja eine Möglichkeit wäre nun ...

Das würde z.B. falsche Anfangs- und End-Tag nicht beachten
z.B.
Delphi-Quellcode:
<test><a></test>

<test><a></test></a>

Alaitoc 11. Feb 2009 10:51

Re: MSXML: Nicht valide Nodes ignorieren
 
Naja das was du jetzt da beschreibst, wäre ja ein Fehler:

"Endtag /test stimmt nicht mit Anfangstag a überein" oder so

Und naja
---1---2---1---
<test><a><test>

Da wüßte ich ja trotzdem das nu <test>.nummer+1 = <a> das Anfangsstück ist auch wenn es fehlerhaft ist.

Edit: Zumindest sollte ich so immer wissen welche beiden "Elemente" zusammengehören...auch wenn sie fehlerhaft sind...natürlich müsste ich dann auch noch einige andere Sachen berücksichtigen z.b. fehlende > oder so


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